mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 17:33:19 +01:00
Compare commits
2 Commits
remove_sup
...
6.1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8585e2e23 | ||
|
|
8ff6c6fd4d |
@@ -1,53 +0,0 @@
|
||||
#!/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,6 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
echo '+cargo fmt --all -- --check'
|
||||
cargo fmt --all -- --check
|
||||
git add -u
|
||||
echo 'find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po'
|
||||
find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po
|
||||
|
||||
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
|
||||
|
||||
echo '+cargo fmt --all -- --check'
|
||||
cargo fmt --all -- --check
|
||||
echo '+cargo +nightly fmt --all -- --check'
|
||||
cargo +nightly fmt --all -- --check
|
||||
echo '+cargo clippy --all -- -D warnings'
|
||||
cargo clippy --all -- -D warnings
|
||||
echo '+cargo cranky'
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,7 +9,6 @@ vendor_*
|
||||
.vscode
|
||||
.~lock.*
|
||||
*.ods#
|
||||
*.patch
|
||||
|
||||
# gnome extension
|
||||
node-modules
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
image: rust:latest
|
||||
|
||||
# Use shallow clone to reduce checkout size
|
||||
variables:
|
||||
GIT_DEPTH: "1"
|
||||
# Put cargo home and target under project dir so we can clean them easily
|
||||
CARGO_HOME: "$CI_PROJECT_DIR/.cargo"
|
||||
CARGO_TARGET_DIR: "$CI_PROJECT_DIR/ci-target"
|
||||
GIT_SUBMODULE_STRATEGY: normal
|
||||
|
||||
# Cache only cargo registries/git metadata to speed dependency fetches.
|
||||
# Avoid caching compiled `target` artifacts which are large and easily fill disk.
|
||||
.rust_cache: &rust_cache
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
# key: $CI_COMMIT_REF_SLUG
|
||||
paths:
|
||||
- .cargo/registry
|
||||
- .cargo/git
|
||||
# Don't include `incremental` to save space
|
||||
# Debug
|
||||
- target/debug/build/
|
||||
- target/debug/deps/
|
||||
- target/debug/.fingerprint/
|
||||
- target/debug/.cargo-lock
|
||||
# Release
|
||||
- target/release/build/
|
||||
- target/release/deps/
|
||||
- target/release/.fingerprint/
|
||||
- target/release/.cargo-lock
|
||||
|
||||
before_script:
|
||||
- df -h
|
||||
- echo "Cleaning stale targets to free space if present"
|
||||
- rm -rf "$CI_PROJECT_DIR/target" "$CI_PROJECT_DIR/ci-target" || true
|
||||
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev libsdl2-dev libsdl2-gfx-dev
|
||||
|
||||
stages:
|
||||
@@ -35,24 +31,20 @@ format:
|
||||
- tags
|
||||
<<: *rust_cache
|
||||
script:
|
||||
- rustup component add rustfmt || true
|
||||
- echo "nightly" > rust-toolchain
|
||||
- rustup component add rustfmt
|
||||
- cargo fmt --check
|
||||
after_script:
|
||||
- du -sh "$CI_PROJECT_DIR/ci-target" || true
|
||||
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||
|
||||
check:
|
||||
except:
|
||||
- tags
|
||||
<<: *rust_cache
|
||||
script:
|
||||
- rustup component add clippy || true
|
||||
- cargo check --locked --workspace
|
||||
- rustup component add clippy
|
||||
- cargo check
|
||||
# deny currently catches too much
|
||||
#- cargo install cargo-deny && cargo deny
|
||||
- cargo install cargo-cranky && cargo cranky
|
||||
after_script:
|
||||
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||
|
||||
test:
|
||||
except:
|
||||
@@ -60,9 +52,7 @@ test:
|
||||
<<: *rust_cache
|
||||
script:
|
||||
- mkdir -p .git/hooks > /dev/null
|
||||
- cargo test --locked --all
|
||||
after_script:
|
||||
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||
- cargo test --all -- --test-threads=1
|
||||
|
||||
release:
|
||||
only:
|
||||
@@ -70,15 +60,11 @@ release:
|
||||
<<: *rust_cache
|
||||
script:
|
||||
- cargo install cargo-vendor-filterer
|
||||
- cargo fetch
|
||||
- make FROZEN=1 && make vendor
|
||||
- make && make vendor
|
||||
artifacts:
|
||||
paths:
|
||||
- vendor_asusctl*.tar.xz
|
||||
- cargo-config
|
||||
expire_in: 1 week
|
||||
after_script:
|
||||
- rm -rf vendor vendor_asusctl*.tar.xz "$CI_PROJECT_DIR/ci-target" || true
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
@@ -86,14 +72,14 @@ pages:
|
||||
- tags
|
||||
<<: *rust_cache
|
||||
script:
|
||||
- cargo doc --locked --document-private-items --no-deps --workspace
|
||||
- cargo doc --document-private-items --no-deps --workspace
|
||||
- rm -rf public
|
||||
- mkdir public
|
||||
- cp -R ci-target/doc/* public
|
||||
- cp -R target/doc/* public
|
||||
- cp extra/index.html public
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
expire_in: 1 week
|
||||
after_script:
|
||||
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: normal
|
||||
|
||||
127
CHANGELOG.md
127
CHANGELOG.md
@@ -2,133 +2,6 @@
|
||||
|
||||
## [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
|
||||
|
||||
3893
Cargo.lock
generated
3893
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
16
Cargo.toml
@@ -1,5 +1,5 @@
|
||||
[workspace.package]
|
||||
version = "6.2.0"
|
||||
version = "6.1.3"
|
||||
rust-version = "1.82"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
@@ -44,8 +44,8 @@ smol = "^2.0"
|
||||
mio = "0.8.11"
|
||||
|
||||
futures-util = "0.3.31"
|
||||
zbus = "5.13.1"
|
||||
logind-zbus = { version = "5.2.0" } #, default-features = false, features = ["non_blocking"] }
|
||||
zbus = "5.1.1"
|
||||
logind-zbus = { version = "5.0.0" } #, default-features = false, features = ["non_blocking"] }
|
||||
|
||||
serde = { version = "^1.0", features = ["serde_derive"] }
|
||||
ron = "*"
|
||||
@@ -57,23 +57,23 @@ glam = { version = "^0.22", features = ["serde"] }
|
||||
gumdrop = "^0.8"
|
||||
udev = { version = "^0.8", features = ["mio"] }
|
||||
rusb = "^0.9"
|
||||
inotify = "^0.10"
|
||||
inotify = "^0.10.0"
|
||||
|
||||
png_pong = "^0.8"
|
||||
pix = "^0.13"
|
||||
tinybmp = "^0.4"
|
||||
gif = "^0.12"
|
||||
tinybmp = "^0.4.0"
|
||||
gif = "^0.12.0"
|
||||
|
||||
versions = "6.2"
|
||||
|
||||
notify-rust = { version = "4.11.5", features = ["z", "async"] }
|
||||
notify-rust = { version = "4.11.4", features = ["z", "async"] }
|
||||
|
||||
sg = { git = "https://github.com/flukejones/sg-rs.git" }
|
||||
|
||||
[profile.release]
|
||||
# thin = 57s, asusd = 9.0M
|
||||
# fat = 72s, asusd = 6.4M
|
||||
lto = "fat"
|
||||
lto = "thin"
|
||||
debug = false
|
||||
opt-level = 3
|
||||
panic = "abort"
|
||||
|
||||
@@ -48,7 +48,7 @@ The LED controller (e.g, aura) enables setting many of the factory modes availab
|
||||
|
||||
#### Supported laptops
|
||||
|
||||
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).
|
||||
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).
|
||||
|
||||
### Charge control
|
||||
|
||||
@@ -420,13 +420,13 @@ To switch to next/previous Aura modes you will need to bind both the aura keys (
|
||||
**Next**
|
||||
|
||||
```
|
||||
asusctl aura -n
|
||||
asusctl led-mode -n
|
||||
```
|
||||
|
||||
**Previous**
|
||||
|
||||
```
|
||||
asusctl aura -p
|
||||
asusctl led-mode -p
|
||||
```
|
||||
|
||||
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
||||
|
||||
70
Makefile
70
Makefile
@@ -17,8 +17,6 @@ BIN_D := asusd
|
||||
BIN_U := asusd-user
|
||||
LEDCFG := aura_support.ron
|
||||
|
||||
DESTDIR_REALPATH = $(shell realpath $(DESTDIR))
|
||||
|
||||
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
|
||||
|
||||
STRIP_BINARIES ?= 0
|
||||
@@ -37,15 +35,6 @@ ifeq ($(X11),1)
|
||||
ARGS += --features "rog-control-center/x11"
|
||||
endif
|
||||
|
||||
# Always use the versions in Cargo.lock by default
|
||||
ARGS += --locked
|
||||
|
||||
# Allow optionally freezing the build to avoid any network access and enforce Cargo.lock strictly
|
||||
FROZEN ?= 0
|
||||
ifeq ($(FROZEN),1)
|
||||
ARGS += --frozen
|
||||
endif
|
||||
|
||||
VENDORED ?= 0
|
||||
ifeq ($(VENDORED),1)
|
||||
ARGS += --frozen
|
||||
@@ -59,38 +48,24 @@ clean:
|
||||
distclean:
|
||||
rm -rf .cargo vendor vendor.tar.xz
|
||||
|
||||
target/$(TARGET)/$(BIN_D): $(SRC)
|
||||
$(MAKE) build
|
||||
|
||||
target/$(TARGET)/$(BIN_C): $(SRC)
|
||||
$(MAKE) build
|
||||
|
||||
target/$(TARGET)/$(BIN_U): $(SRC)
|
||||
$(MAKE) build
|
||||
|
||||
target/$(TARGET)/$(BIN_ROG): $(SRC)
|
||||
$(MAKE) build
|
||||
|
||||
install-asusd: target/$(TARGET)/$(BIN_D)
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||
|
||||
install-asusctl: target/$(TARGET)/$(BIN_C)
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||
|
||||
install-asusd_user: target/$(TARGET)/$(BIN_U)
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||
|
||||
install-rog_gui: target/$(TARGET)/$(BIN_ROG)
|
||||
install-program:
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||
|
||||
.PHONY: install-asusd install-asusctl install-asusd_user install-rog_gui
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||
|
||||
install-program: install-asusd install-asusctl install-asusd_user install-rog_gui
|
||||
|
||||
install-data-rog_gui:
|
||||
install-data:
|
||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
||||
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/rog-gui/layouts/{}" \;
|
||||
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
||||
|
||||
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
||||
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
||||
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
||||
|
||||
$(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service"
|
||||
$(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service"
|
||||
|
||||
$(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"
|
||||
@@ -106,24 +81,9 @@ install-data-rog_gui:
|
||||
$(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-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
|
||||
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
||||
|
||||
install: install-program install-data
|
||||
$(INSTALL_DATA) "./LICENSE" "$(DESTDIR)$(datarootdir)/asusctl/LICENSE"
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||
@@ -158,8 +118,6 @@ vendor:
|
||||
mv .cargo/config ./cargo-config
|
||||
rm -rf .cargo
|
||||
rm -rf vendor
|
||||
# Ensure cargo-vendor-filterer is installed (CI installs it already)
|
||||
command -v cargo-vendor-filterer >/dev/null 2>&1 || cargo install --locked cargo-vendor-filterer
|
||||
cargo vendor-filterer --all-features --platform x86_64-unknown-linux-gnu vendor
|
||||
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
|
||||
rm -rf vendor
|
||||
|
||||
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
|
||||
to this:
|
||||
|
||||
```plain
|
||||
```
|
||||
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```plain
|
||||
```
|
||||
Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown]
|
||||
```
|
||||
|
||||
@@ -74,56 +74,43 @@ The list is a bit outdated as many features have been enabled in the Linux kerne
|
||||
- [x] Toggle bios setting for boot/POST sound
|
||||
- [x] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops)
|
||||
|
||||
## GUI
|
||||
# GUI
|
||||
|
||||
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
|
||||
|
||||
**NOTE**: Xorg is not supported.
|
||||
|
||||
## BUILDING
|
||||
# BUILDING
|
||||
|
||||
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/).
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
**fedora:**
|
||||
|
||||
```sh
|
||||
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||
make
|
||||
sudo make install
|
||||
|
||||
**openSUSE:**
|
||||
|
||||
Works with KDE Plasma (without GTK packages)
|
||||
|
||||
```sh
|
||||
zypper in -t pattern devel_basis
|
||||
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
zypper in -t pattern devel_basis
|
||||
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||
make
|
||||
sudo make install
|
||||
|
||||
**Debian(unsuported):**
|
||||
|
||||
officially unsuported,but you can still try and test it by yourself(some features may not be available).
|
||||
|
||||
```sh
|
||||
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
make
|
||||
sudo make install
|
||||
|
||||
**Ubuntu, Popos (unsuported):**
|
||||
|
||||
```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
|
||||
```
|
||||
instructions removed as outdated
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -141,15 +128,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.
|
||||
|
||||
```sh
|
||||
systemctl daemon-reload && systemctl restart asusd
|
||||
```
|
||||
$ systemctl daemon-reload && systemctl restart asusd
|
||||
```
|
||||
|
||||
## Uninstalling
|
||||
|
||||
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
||||
|
||||
## Contributing
|
||||
# Contributing
|
||||
|
||||
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
|
||||
|
||||
@@ -157,17 +144,17 @@ Generation of the bindings with `make bindings` requires `typeshare` to be insta
|
||||
|
||||
Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`.
|
||||
|
||||
## OTHER
|
||||
# OTHER
|
||||
|
||||
### AniMe Matrix simulator
|
||||
## AniMe Matrix simulator
|
||||
|
||||
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display.
|
||||
|
||||
### Supporting more laptops
|
||||
## Supporting more laptops
|
||||
|
||||
Please file a support request.
|
||||
|
||||
## License & Trademarks
|
||||
# License & Trademarks
|
||||
|
||||
Mozilla Public License 2 (MPL-2.0)
|
||||
|
||||
|
||||
@@ -27,15 +27,3 @@ zbus.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
|
||||
[package.metadata.deb]
|
||||
license-file = ["../LICENSE", "4"]
|
||||
extended-description = """\
|
||||
An utility for Linux to control many aspects of various ASUS laptops
|
||||
but can also be used with non-asus laptops with reduced features."""
|
||||
depends = "$auto"
|
||||
section = "utility"
|
||||
priority = "optional"
|
||||
assets = [
|
||||
["target/release/asusctl", "usr/bin/", "755"],
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
Path::new(&args[1]),
|
||||
None,
|
||||
args[2].parse::<f32>().unwrap(),
|
||||
AnimeType::GA401,
|
||||
AnimeType::GA401
|
||||
)?;
|
||||
|
||||
let anime_type = get_anime_type();
|
||||
|
||||
@@ -21,14 +21,11 @@ fn main() {
|
||||
let brightness = args[2].parse::<f32>().unwrap();
|
||||
let anime_type = get_anime_type();
|
||||
let mut seq = Sequences::new(anime_type);
|
||||
seq.insert(
|
||||
0,
|
||||
&ActionLoader::AsusAnimation {
|
||||
file: path.into(),
|
||||
time: rog_anime::AnimTime::Infinite,
|
||||
brightness,
|
||||
},
|
||||
)
|
||||
seq.insert(0, &ActionLoader::AsusAnimation {
|
||||
file: path.into(),
|
||||
time: rog_anime::AnimTime::Infinite,
|
||||
brightness
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
loop {
|
||||
|
||||
@@ -27,10 +27,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
args[3].parse::<f32>().unwrap(),
|
||||
Vec2::new(
|
||||
args[4].parse::<f32>().unwrap(),
|
||||
args[5].parse::<f32>().unwrap(),
|
||||
args[5].parse::<f32>().unwrap()
|
||||
),
|
||||
args[6].parse::<f32>().unwrap(),
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?).unwrap();
|
||||
|
||||
@@ -30,10 +30,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
args[3].parse::<f32>().unwrap(),
|
||||
Vec2::new(
|
||||
args[4].parse::<f32>().unwrap(),
|
||||
args[5].parse::<f32>().unwrap(),
|
||||
args[5].parse::<f32>().unwrap()
|
||||
),
|
||||
args[6].parse::<f32>().unwrap(),
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
loop {
|
||||
|
||||
@@ -36,10 +36,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Colour {
|
||||
r: 200,
|
||||
g: 110,
|
||||
b: 0,
|
||||
b: 0
|
||||
},
|
||||
100,
|
||||
10,
|
||||
10
|
||||
));
|
||||
seq.push(zone);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ pub struct AnimeCommand {
|
||||
#[options(no_short, meta = "", help = "Off with his head!!!")]
|
||||
pub off_with_his_head: Option<bool>,
|
||||
#[options(command)]
|
||||
pub command: Option<AnimeActions>,
|
||||
pub command: Option<AnimeActions>
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -54,7 +54,7 @@ pub enum AnimeActions {
|
||||
#[options(help = "display an animated diagonal/pixel-perfect GIF")]
|
||||
PixelGif(AnimeGifDiagonal),
|
||||
#[options(help = "change which builtin animations are shown")]
|
||||
SetBuiltins(Builtins),
|
||||
SetBuiltins(Builtins)
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -82,7 +82,7 @@ pub struct Builtins {
|
||||
)]
|
||||
pub shutdown: AnimShutdown,
|
||||
#[options(meta = "", help = "set/apply the animations <true/false>")]
|
||||
pub set: Option<bool>,
|
||||
pub set: Option<bool>
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -100,7 +100,7 @@ pub struct AnimeImage {
|
||||
#[options(meta = "", default = "0.0", help = "the angle in radians")]
|
||||
pub angle: f32,
|
||||
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
||||
pub bright: f32,
|
||||
pub bright: f32
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -110,7 +110,7 @@ pub struct AnimeImageDiagonal {
|
||||
#[options(meta = "", help = "full path to the png to display")]
|
||||
pub path: String,
|
||||
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
||||
pub bright: f32,
|
||||
pub bright: f32
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -134,7 +134,7 @@ pub struct AnimeGif {
|
||||
default = "1",
|
||||
help = "how many loops to play - 0 is infinite"
|
||||
)]
|
||||
pub loops: u32,
|
||||
pub loops: u32
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -150,5 +150,5 @@ pub struct AnimeGifDiagonal {
|
||||
default = "1",
|
||||
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>")]
|
||||
pub boot: Option<bool>,
|
||||
#[options(meta = "", help = "Control suspend animations <true/false>")]
|
||||
pub sleep: Option<bool>,
|
||||
pub sleep: Option<bool>
|
||||
}
|
||||
|
||||
#[derive(Options, Debug)]
|
||||
@@ -25,7 +25,7 @@ pub struct LedPowerCommand2 {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(command)]
|
||||
pub command: Option<SetAuraZoneEnabled>,
|
||||
pub command: Option<SetAuraZoneEnabled>
|
||||
}
|
||||
|
||||
#[derive(Options, Debug)]
|
||||
@@ -42,7 +42,7 @@ pub enum SetAuraZoneEnabled {
|
||||
#[options(help = "")]
|
||||
RearGlow(AuraPowerStates),
|
||||
#[options(help = "")]
|
||||
Ally(AuraPowerStates),
|
||||
Ally(AuraPowerStates)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Options)]
|
||||
@@ -56,12 +56,12 @@ pub struct AuraPowerStates {
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub sleep: bool,
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub shutdown: bool,
|
||||
pub shutdown: bool
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct LedBrightness {
|
||||
level: Option<u8>,
|
||||
level: Option<u8>
|
||||
}
|
||||
impl LedBrightness {
|
||||
pub fn new(level: Option<u8>) -> Self {
|
||||
@@ -96,7 +96,7 @@ impl ToString for LedBrightness {
|
||||
Some(0x00) => "low",
|
||||
Some(0x01) => "med",
|
||||
Some(0x02) => "high",
|
||||
_ => "unknown",
|
||||
_ => "unknown"
|
||||
};
|
||||
s.to_owned()
|
||||
}
|
||||
@@ -113,7 +113,7 @@ pub struct SingleSpeed {
|
||||
meta = "",
|
||||
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)]
|
||||
@@ -129,7 +129,7 @@ pub struct SingleSpeedDirection {
|
||||
meta = "",
|
||||
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)]
|
||||
@@ -143,7 +143,7 @@ pub struct SingleColour {
|
||||
meta = "",
|
||||
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)]
|
||||
@@ -159,7 +159,7 @@ pub struct SingleColourSpeed {
|
||||
meta = "",
|
||||
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)]
|
||||
@@ -177,11 +177,10 @@ pub struct TwoColourSpeed {
|
||||
meta = "",
|
||||
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)]
|
||||
#[allow(dead_code)]
|
||||
pub struct MultiZone {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
@@ -192,11 +191,10 @@ pub struct MultiZone {
|
||||
#[options(short = "c", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||
pub colour3: Colour,
|
||||
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||
pub colour4: Colour,
|
||||
pub colour4: Colour
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Options)]
|
||||
#[allow(dead_code)]
|
||||
pub struct MultiColourSpeed {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
@@ -209,7 +207,7 @@ pub struct MultiColourSpeed {
|
||||
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||
pub colour4: Colour,
|
||||
#[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.
|
||||
@@ -241,7 +239,7 @@ pub enum SetAuraBuiltin {
|
||||
#[options(help = "set a vertical line zooming from left")]
|
||||
Comet(SingleColour), // 11
|
||||
#[options(help = "set a wide vertical line zooming from left")]
|
||||
Flash(SingleColour), // 12
|
||||
Flash(SingleColour) // 12
|
||||
}
|
||||
|
||||
impl Default for SetAuraBuiltin {
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct CliStart {
|
||||
#[options(help = "Toggle one-shot battery charge to 100%")]
|
||||
pub one_shot_chg: bool,
|
||||
#[options(command)]
|
||||
pub command: Option<CliCommand>,
|
||||
pub command: Option<CliCommand>
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -53,9 +53,7 @@ pub enum CliCommand {
|
||||
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"
|
||||
)]
|
||||
Armoury(ArmouryCommand),
|
||||
#[options(name = "backlight", help = "Set screen backlight levels")]
|
||||
Backlight(BacklightCommand),
|
||||
Armoury(ArmouryCommand)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Options)]
|
||||
@@ -73,17 +71,7 @@ pub struct ProfileCommand {
|
||||
pub profile_get: bool,
|
||||
|
||||
#[options(meta = "", help = "set the active profile")]
|
||||
pub profile_set: Option<PlatformProfile>,
|
||||
|
||||
#[options(short = "a", meta = "", help = "set the profile to use on AC power")]
|
||||
pub profile_set_ac: Option<PlatformProfile>,
|
||||
|
||||
#[options(
|
||||
short = "b",
|
||||
meta = "",
|
||||
help = "set the profile to use on battery power"
|
||||
)]
|
||||
pub profile_set_bat: Option<PlatformProfile>,
|
||||
pub profile_set: Option<PlatformProfile>
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
@@ -95,13 +83,13 @@ pub struct LedModeCommand {
|
||||
#[options(help = "switch to previous aura mode")]
|
||||
pub prev_mode: bool,
|
||||
#[options(command)]
|
||||
pub command: Option<SetAuraBuiltin>,
|
||||
pub command: Option<SetAuraBuiltin>
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct GraphicsCommand {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
pub help: bool
|
||||
}
|
||||
|
||||
#[derive(Options, Debug)]
|
||||
@@ -112,23 +100,5 @@ pub struct ArmouryCommand {
|
||||
free,
|
||||
help = "append each value name followed by the value to set. `-1` sets to default"
|
||||
)]
|
||||
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>,
|
||||
pub free: Vec<String>
|
||||
}
|
||||
|
||||
@@ -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%. \
|
||||
`--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 fan_curve_cli::FanCurveCommand;
|
||||
use gumdrop::{Opt, Options};
|
||||
use log::{error, info, LevelFilter};
|
||||
use log::{error, info};
|
||||
use rog_anime::usb::get_anime_type;
|
||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||
@@ -19,7 +19,6 @@ use rog_dbus::list_iface_blocking;
|
||||
use rog_dbus::scsi_aura::ScsiAuraProxyBlocking;
|
||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||
use rog_dbus::zbus_backlight::BacklightProxyBlocking;
|
||||
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
||||
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
||||
@@ -44,16 +43,12 @@ mod scsi_cli;
|
||||
mod slash_cli;
|
||||
|
||||
fn main() {
|
||||
// Ensure tracing spans are quiet by default unless user overrides
|
||||
if std::env::var_os("RUST_LOG").is_none() {
|
||||
std::env::set_var("RUST_LOG", "warn,tracing=error,zbus=error");
|
||||
}
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
.parse_default_env()
|
||||
.filter_level(LevelFilter::Info)
|
||||
.target(env_logger::Target::Stderr)
|
||||
.target(env_logger::Target::Stdout)
|
||||
.format_timestamp(None)
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
let self_version = env!("CARGO_PKG_VERSION");
|
||||
@@ -79,36 +74,22 @@ fn main() {
|
||||
println!("\nError: {e}\n");
|
||||
print_info();
|
||||
}) {
|
||||
let asusd_version = match platform_proxy.version() {
|
||||
Ok(version) => version,
|
||||
Err(e) => {
|
||||
let asusd_version = platform_proxy
|
||||
.version()
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Could not get asusd version: {e:?}\nIs asusd.service running? {}",
|
||||
check_service("asusd")
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
})
|
||||
.unwrap();
|
||||
if asusd_version != self_version {
|
||||
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||
return;
|
||||
}
|
||||
|
||||
let supported_properties = match platform_proxy.supported_properties() {
|
||||
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;
|
||||
}
|
||||
};
|
||||
let supported_properties = platform_proxy.supported_properties().unwrap();
|
||||
let supported_interfaces = list_iface_blocking().unwrap();
|
||||
|
||||
if parsed.version {
|
||||
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||
@@ -125,7 +106,7 @@ fn main() {
|
||||
fn print_error_help(
|
||||
err: &dyn std::error::Error,
|
||||
supported_interfaces: &[String],
|
||||
supported_properties: &[Properties],
|
||||
supported_properties: &[Properties]
|
||||
) {
|
||||
check_service("asusd");
|
||||
println!("\nError: {}\n", err);
|
||||
@@ -166,7 +147,7 @@ fn check_service(name: &str) -> bool {
|
||||
|
||||
fn find_iface<T>(iface_name: &str) -> Result<Vec<T>, Box<dyn std::error::Error>>
|
||||
where
|
||||
T: ProxyImpl<'static> + From<zbus::Proxy<'static>>,
|
||||
T: ProxyImpl<'static> + From<zbus::Proxy<'static>>
|
||||
{
|
||||
let conn = zbus::blocking::Connection::system().unwrap();
|
||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").unwrap();
|
||||
@@ -193,7 +174,7 @@ where
|
||||
T::builder(&conn)
|
||||
.path(path.clone())?
|
||||
.destination("xyz.ljones.Asusd")?
|
||||
.build()?,
|
||||
.build()?
|
||||
);
|
||||
}
|
||||
return Ok(ctrl);
|
||||
@@ -206,7 +187,7 @@ fn do_parsed(
|
||||
parsed: &CliStart,
|
||||
supported_interfaces: &[String],
|
||||
supported_properties: &[Properties],
|
||||
conn: Connection,
|
||||
conn: Connection
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match &parsed.command {
|
||||
Some(CliCommand::Aura(mode)) => handle_led_mode(mode)?,
|
||||
@@ -223,7 +204,6 @@ fn do_parsed(
|
||||
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
|
||||
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?,
|
||||
Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?,
|
||||
Some(CliCommand::Backlight(cmd)) => handle_backlight(cmd)?,
|
||||
None => {
|
||||
if (!parsed.show_supported
|
||||
&& parsed.kbd_bright.is_none()
|
||||
@@ -279,18 +259,12 @@ fn do_parsed(
|
||||
return false;
|
||||
}
|
||||
|
||||
if command.trim().starts_with("armoury")
|
||||
if command.trim().starts_with("platform")
|
||||
&& !supported_interfaces.contains(&"xyz.ljones.AsusArmoury".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if command.trim().starts_with("backlight")
|
||||
&& !supported_interfaces.contains(&"xyz.ljones.Backlight".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if !dev_type.is_old_laptop()
|
||||
&& !dev_type.is_tuf_laptop()
|
||||
&& command.trim().starts_with("aura-power-old")
|
||||
@@ -321,7 +295,7 @@ fn do_parsed(
|
||||
let level = aura.brightness()?;
|
||||
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 {
|
||||
@@ -393,46 +367,6 @@ fn do_gfx() {
|
||||
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>> {
|
||||
if (cmd.command.is_none()
|
||||
&& cmd.enable_display.is_none()
|
||||
@@ -510,7 +444,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
image.angle,
|
||||
Vec2::new(image.x_pos, image.y_pos),
|
||||
image.bright,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?)?;
|
||||
@@ -529,7 +463,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
Path::new(&image.path),
|
||||
None,
|
||||
image.bright,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
proxy.write(matrix.into_data_buffer(anime_type)?)?;
|
||||
@@ -551,7 +485,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
Vec2::new(gif.x_pos, gif.y_pos),
|
||||
AnimTime::Count(1),
|
||||
gif.bright,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
let mut loops = gif.loops as i32;
|
||||
@@ -582,7 +516,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
Path::new(&gif.path),
|
||||
AnimTime::Count(1),
|
||||
gif.bright,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
let mut loops = gif.loops as i32;
|
||||
@@ -615,7 +549,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
boot: builtins.boot,
|
||||
awake: builtins.awake,
|
||||
sleep: builtins.sleep,
|
||||
shutdown: builtins.shutdown,
|
||||
shutdown: builtins.shutdown
|
||||
})?;
|
||||
}
|
||||
}
|
||||
@@ -641,7 +575,6 @@ fn handle_slash(cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
&& cmd.show_on_sleep.is_none()
|
||||
&& cmd.show_on_battery.is_none()
|
||||
&& cmd.show_battery_warning.is_none()
|
||||
// && cmd.show_on_lid_closed.is_none()
|
||||
&& cmd.mode.is_none()
|
||||
&& !cmd.list
|
||||
&& !cmd.enable
|
||||
@@ -687,9 +620,6 @@ fn handle_slash(cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Some(show) = cmd.show_battery_warning {
|
||||
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 {
|
||||
let res = SlashMode::list();
|
||||
@@ -882,7 +812,7 @@ fn handle_led_power1(power: &LedPowerCommand1) -> Result<(), Box<dyn std::error:
|
||||
|
||||
fn handle_led_power_1_do_1866(
|
||||
aura: &AuraProxyBlocking,
|
||||
power: &LedPowerCommand1,
|
||||
power: &LedPowerCommand1
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut states = Vec::new();
|
||||
if power.keyboard {
|
||||
@@ -891,7 +821,7 @@ fn handle_led_power_1_do_1866(
|
||||
boot: power.boot.unwrap_or_default(),
|
||||
awake: power.awake.unwrap_or_default(),
|
||||
sleep: power.sleep.unwrap_or_default(),
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
});
|
||||
}
|
||||
if power.lightbar {
|
||||
@@ -900,7 +830,7 @@ fn handle_led_power_1_do_1866(
|
||||
boot: power.boot.unwrap_or_default(),
|
||||
awake: power.awake.unwrap_or_default(),
|
||||
sleep: power.sleep.unwrap_or_default(),
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
});
|
||||
}
|
||||
|
||||
@@ -962,7 +892,7 @@ fn handle_led_power2(power: &LedPowerCommand2) -> Result<(), Box<dyn std::error:
|
||||
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(PowerZones::Lightbar, l),
|
||||
aura_cli::SetAuraZoneEnabled::Lid(l) => set(PowerZones::Lid, l),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,20 +906,14 @@ fn handle_led_power2(power: &LedPowerCommand2) -> Result<(), Box<dyn std::error:
|
||||
fn handle_throttle_profile(
|
||||
conn: &Connection,
|
||||
supported: &[Properties],
|
||||
cmd: &ProfileCommand,
|
||||
cmd: &ProfileCommand
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if !supported.contains(&Properties::ThrottlePolicy) {
|
||||
println!("Profiles not supported by either this kernel or by the laptop.");
|
||||
return Err(ProfileError::NotSupported.into());
|
||||
}
|
||||
|
||||
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.next && !cmd.list && cmd.profile_set.is_none() && !cmd.profile_get {
|
||||
if !cmd.help {
|
||||
println!("Missing arg or command\n");
|
||||
}
|
||||
@@ -1003,31 +927,22 @@ fn handle_throttle_profile(
|
||||
|
||||
let proxy = PlatformProxyBlocking::new(conn)?;
|
||||
let current = proxy.platform_profile()?;
|
||||
let choices = proxy.platform_profile_choices()?;
|
||||
|
||||
if cmd.next {
|
||||
proxy.set_platform_profile(PlatformProfile::next(current, &choices))?;
|
||||
proxy.set_platform_profile(current.next())?;
|
||||
} else if let Some(profile) = cmd.profile_set {
|
||||
proxy.set_platform_profile(profile)?;
|
||||
} else if let Some(profile) = cmd.profile_set_ac {
|
||||
proxy.set_platform_profile_on_ac(profile)?;
|
||||
} else if let Some(profile) = cmd.profile_set_bat {
|
||||
proxy.set_platform_profile_on_battery(profile)?;
|
||||
}
|
||||
|
||||
if cmd.list {
|
||||
for p in &choices {
|
||||
let res = PlatformProfile::list();
|
||||
for p in &res {
|
||||
println!("{:?}", p);
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.profile_get {
|
||||
println!("Active profile is {current:?}");
|
||||
println!("Profile on AC is {:?}", proxy.platform_profile_on_ac()?);
|
||||
println!(
|
||||
"Profile on Battery is {:?}",
|
||||
proxy.platform_profile_on_battery()?
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1035,7 +950,7 @@ fn handle_throttle_profile(
|
||||
|
||||
fn handle_fan_curve(
|
||||
conn: &Connection,
|
||||
cmd: &FanCurveCommand,
|
||||
cmd: &FanCurveCommand
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let Ok(fan_proxy) = FanCurvesProxyBlocking::new(conn).map_err(|e| {
|
||||
println!("Fan-curves not supported by either this kernel or by the laptop: {e:?}");
|
||||
@@ -1188,11 +1103,10 @@ fn print_firmware_attr(attr: &AsusArmouryProxyBlocking) -> Result<(), Box<dyn st
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::manual_is_multiple_of, clippy::nonminimal_bool)]
|
||||
fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||
{
|
||||
if cmd.free.is_empty() || (cmd.free.len() % 2 != 0) || cmd.help {
|
||||
const USAGE: &str = "Usage: asusctl armoury panel_overdrive 1 nv_dynamic_boost 5";
|
||||
if cmd.free.is_empty() || cmd.free.len() % 2 != 0 || cmd.help {
|
||||
const USAGE: &str = "Usage: asusctl platform panel_overdrive 1 nv_dynamic_boost 5";
|
||||
if cmd.free.len() % 2 != 0 {
|
||||
println!(
|
||||
"Incorrect number of args, each attribute label must be paired with a setting:"
|
||||
|
||||
@@ -31,5 +31,5 @@ pub struct ScsiCommand {
|
||||
pub colours: Vec<Colour>,
|
||||
|
||||
#[options(help = "list available animations")]
|
||||
pub list: bool,
|
||||
pub list: bool
|
||||
}
|
||||
|
||||
@@ -26,12 +26,10 @@ pub struct SlashCommand {
|
||||
pub show_on_sleep: Option<bool>,
|
||||
#[options(short = "b", meta = "", help = "Show the animation on battery")]
|
||||
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(
|
||||
short = "w",
|
||||
meta = "",
|
||||
help = "Show the low-battery warning animation"
|
||||
)]
|
||||
pub show_battery_warning: Option<bool>,
|
||||
pub show_battery_warning: Option<bool>
|
||||
}
|
||||
|
||||
@@ -32,16 +32,3 @@ config-traits = { path = "../config-traits" }
|
||||
|
||||
zbus.workspace = true
|
||||
env_logger.workspace = true
|
||||
|
||||
[package.metadata.deb]
|
||||
license-file = ["../LICENSE", "4"]
|
||||
extended-description = """\
|
||||
An user utility for Linux to control fancy things on various ASUS laptops
|
||||
like keyboard effects or anime matrix animation cycles."""
|
||||
depends = "$auto"
|
||||
section = "utility"
|
||||
priority = "optional"
|
||||
assets = [
|
||||
["target/release/asusd-user", "usr/bin/", "755"],
|
||||
["../asusd_user-fakeinstall/usr/lib/systemd/user/*", "usr/lib/systemd/user/", "644"],
|
||||
]
|
||||
|
||||
@@ -21,7 +21,7 @@ fn root_conf_dir() -> PathBuf {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct ConfigAnime {
|
||||
pub name: String,
|
||||
pub anime: Vec<ActionLoader>,
|
||||
pub anime: Vec<ActionLoader>
|
||||
}
|
||||
|
||||
impl ConfigAnime {
|
||||
@@ -52,8 +52,8 @@ impl Default for ConfigAnime {
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
None,
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
Duration::from_secs(2)
|
||||
))
|
||||
},
|
||||
ActionLoader::AsusAnimation {
|
||||
file: "/usr/share/asusd/anime/asus/rog/Sunset.gif".into(),
|
||||
@@ -61,8 +61,8 @@ impl Default for ConfigAnime {
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(6),
|
||||
None,
|
||||
Duration::from_secs(3),
|
||||
)),
|
||||
Duration::from_secs(3)
|
||||
))
|
||||
},
|
||||
ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||
@@ -73,8 +73,8 @@ impl Default for ConfigAnime {
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
Duration::from_secs(2)
|
||||
))
|
||||
},
|
||||
ActionLoader::Image {
|
||||
file: "/usr/share/asusd/anime/custom/rust.png".into(),
|
||||
@@ -84,9 +84,9 @@ impl Default for ConfigAnime {
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
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::ImageAnimation {
|
||||
@@ -95,9 +95,9 @@ impl Default for ConfigAnime {
|
||||
angle: 0.0,
|
||||
translation: Vec2::new(3.0, 2.0),
|
||||
brightness: 0.5,
|
||||
time: AnimTime::Count(2),
|
||||
time: AnimTime::Count(2)
|
||||
},
|
||||
],
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ impl StdConfigLoad for ConfigAnime {}
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct ConfigAura {
|
||||
pub name: String,
|
||||
pub aura: AuraSequences,
|
||||
pub aura: AuraSequences
|
||||
}
|
||||
|
||||
impl ConfigAura {
|
||||
@@ -139,14 +139,14 @@ impl Default for ConfigAura {
|
||||
Colour {
|
||||
r: 255,
|
||||
g: 0,
|
||||
b: 20,
|
||||
b: 20
|
||||
},
|
||||
Colour {
|
||||
r: 20,
|
||||
g: 255,
|
||||
b: 0,
|
||||
b: 0
|
||||
},
|
||||
Speed::Low,
|
||||
Speed::Low
|
||||
));
|
||||
|
||||
seq.push(key.clone());
|
||||
@@ -161,7 +161,7 @@ impl Default for ConfigAura {
|
||||
LedCode::F,
|
||||
Colour { r: 255, g: 0, b: 0 },
|
||||
Colour { r: 255, g: 0, b: 0 },
|
||||
Speed::High,
|
||||
Speed::High
|
||||
));
|
||||
seq.push(key);
|
||||
|
||||
@@ -176,13 +176,13 @@ impl Default for ConfigAura {
|
||||
LedCode::N9,
|
||||
Colour { r: 0, g: 0, b: 255 },
|
||||
80,
|
||||
40,
|
||||
40
|
||||
));
|
||||
seq.push(key);
|
||||
|
||||
Self {
|
||||
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
|
||||
pub active_anime: Option<String>,
|
||||
/// 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 {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
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
|
||||
fade_in: u64,
|
||||
/// Used only for `TimeType::Timer`, milliseonds to fade the image out for
|
||||
fade_out: u64,
|
||||
fade_out: u64
|
||||
}
|
||||
|
||||
impl From<Timer> for AnimTime {
|
||||
@@ -46,7 +46,7 @@ impl From<Timer> for AnimTime {
|
||||
}
|
||||
}
|
||||
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 {
|
||||
Timer,
|
||||
Count,
|
||||
Infinite,
|
||||
Infinite
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
sequences: Sequences,
|
||||
client: AnimeProxyBlocking<'a>,
|
||||
do_early_return: Arc<AtomicBool>,
|
||||
do_early_return: Arc<AtomicBool>
|
||||
}
|
||||
|
||||
impl CtrlAnimeInner<'static> {
|
||||
pub fn new(
|
||||
sequences: Sequences,
|
||||
client: AnimeProxyBlocking<'static>,
|
||||
do_early_return: Arc<AtomicBool>,
|
||||
do_early_return: Arc<AtomicBool>
|
||||
) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
sequences,
|
||||
client,
|
||||
do_early_return,
|
||||
do_early_return
|
||||
})
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ pub struct CtrlAnime<'a> {
|
||||
client: AnimeProxyBlocking<'a>,
|
||||
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
||||
/// Must be the same Atomic as in CtrlAnimeInner
|
||||
inner_early_return: Arc<AtomicBool>,
|
||||
inner_early_return: Arc<AtomicBool>
|
||||
}
|
||||
|
||||
impl CtrlAnime<'static> {
|
||||
@@ -138,13 +138,13 @@ impl CtrlAnime<'static> {
|
||||
config: Arc<Mutex<ConfigAnime>>,
|
||||
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
||||
client: AnimeProxyBlocking<'static>,
|
||||
inner_early_return: Arc<AtomicBool>,
|
||||
inner_early_return: Arc<AtomicBool>
|
||||
) -> Result<Self, Error> {
|
||||
Ok(CtrlAnime {
|
||||
config,
|
||||
client,
|
||||
inner,
|
||||
inner_early_return,
|
||||
inner_early_return
|
||||
})
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ impl CtrlAnime<'static> {
|
||||
index: u32,
|
||||
file: &str,
|
||||
time: Timer,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let time: AnimTime = time.into();
|
||||
@@ -182,7 +182,7 @@ impl CtrlAnime<'static> {
|
||||
let action = ActionLoader::AsusAnimation {
|
||||
file: file.into(),
|
||||
brightness,
|
||||
time,
|
||||
time
|
||||
};
|
||||
|
||||
// Must make the inner run loop return early
|
||||
@@ -216,7 +216,7 @@ impl CtrlAnime<'static> {
|
||||
angle: f32,
|
||||
xy: (f32, f32),
|
||||
time: Timer,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let time: AnimTime = time.into();
|
||||
@@ -228,7 +228,7 @@ impl CtrlAnime<'static> {
|
||||
angle,
|
||||
translation,
|
||||
brightness,
|
||||
time,
|
||||
time
|
||||
};
|
||||
|
||||
// Must make the inner run loop return early
|
||||
@@ -261,7 +261,7 @@ impl CtrlAnime<'static> {
|
||||
angle: f32,
|
||||
xy: (f32, f32),
|
||||
time: Timer,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let file = Path::new(&file);
|
||||
@@ -272,7 +272,7 @@ impl CtrlAnime<'static> {
|
||||
angle,
|
||||
translation: Vec2::new(xy.0, xy.1),
|
||||
brightness,
|
||||
time,
|
||||
time
|
||||
};
|
||||
|
||||
// Must make the inner run loop return early
|
||||
|
||||
@@ -61,16 +61,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
CtrlAnimeInner::new(
|
||||
anime,
|
||||
anime_proxy_blocking.clone(),
|
||||
early_return.clone(),
|
||||
early_return.clone()
|
||||
)
|
||||
.unwrap(),
|
||||
.unwrap()
|
||||
));
|
||||
// Need new client object for dbus control part
|
||||
let anime_control = CtrlAnime::new(
|
||||
anime_config,
|
||||
inner.clone(),
|
||||
anime_proxy_blocking,
|
||||
early_return,
|
||||
early_return
|
||||
)
|
||||
.unwrap();
|
||||
anime_control.add_to_server(&mut connection).await;
|
||||
|
||||
@@ -8,7 +8,7 @@ pub enum Error {
|
||||
ConfigLoadFail,
|
||||
ConfigLockFail,
|
||||
XdgVars,
|
||||
Anime(AnimeError),
|
||||
Anime(AnimeError)
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -19,7 +19,7 @@ impl fmt::Display for Error {
|
||||
Error::ConfigLoadFail => write!(f, "Failed to load user config"),
|
||||
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
||||
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,
|
||||
time: u32,
|
||||
count: u32,
|
||||
brightness: f64,
|
||||
brightness: f64
|
||||
) -> zbus::Result<String>;
|
||||
|
||||
/// InsertImage method
|
||||
@@ -43,7 +43,7 @@ trait Daemon {
|
||||
scale: f64,
|
||||
angle: f64,
|
||||
xy: &(f64, f64),
|
||||
brightness: f64,
|
||||
brightness: f64
|
||||
) -> zbus::Result<String>;
|
||||
|
||||
/// InsertImageGif method
|
||||
@@ -56,7 +56,7 @@ trait Daemon {
|
||||
xy: &(f64, f64),
|
||||
time: u32,
|
||||
count: u32,
|
||||
brightness: f64,
|
||||
brightness: f64
|
||||
) -> zbus::Result<String>;
|
||||
|
||||
/// InsertPause method
|
||||
|
||||
@@ -45,18 +45,3 @@ concat-idents.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
cargo-husky.workspace = true
|
||||
|
||||
[package.metadata.deb]
|
||||
license-file = ["../LICENSE", "4"]
|
||||
extended-description = """\
|
||||
The dbus server for asusctl and rog-control-center applications."""
|
||||
depends = "$auto"
|
||||
section = "utility"
|
||||
priority = "optional"
|
||||
assets = [
|
||||
["target/release/asusd", "usr/bin/", "755"],
|
||||
["../asusd-fakeinstall/usr/lib/systemd/system/*", "usr/lib/systemd/system/", "644"],
|
||||
["../asusd-fakeinstall/usr/lib/udev/rules.d/*", "usr/lib/udev/rules.d/", "644"],
|
||||
["../asusd-fakeinstall/usr/share/asusd/*", "usr/share/share/asusd/", "644"],
|
||||
["../asusd-fakeinstall/usr/share/dbus-1/system.d/*", "usr/share/dbus-1/system.d/", "644"],
|
||||
]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use log::{debug, error, info, warn};
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info};
|
||||
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
||||
use rog_platform::power::AsusPower;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use zbus::object_server::SignalEmitter;
|
||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
|
||||
use zbus::{fdo, interface, Connection};
|
||||
@@ -20,7 +20,7 @@ const MOD_NAME: &str = "asus_armoury";
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
|
||||
pub struct PossibleValues {
|
||||
strings: Vec<String>,
|
||||
nums: Vec<i32>,
|
||||
nums: Vec<i32>
|
||||
}
|
||||
|
||||
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
|
||||
@@ -33,7 +33,7 @@ pub struct AsusArmouryAttribute {
|
||||
config: Arc<Mutex<Config>>,
|
||||
/// platform control required here for access to PPD or Throttle profile
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
power: AsusPower
|
||||
}
|
||||
|
||||
impl AsusArmouryAttribute {
|
||||
@@ -41,39 +41,16 @@ impl AsusArmouryAttribute {
|
||||
attr: Attribute,
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
config: Arc<Mutex<Config>>,
|
||||
config: Arc<Mutex<Config>>
|
||||
) -> Self {
|
||||
Self {
|
||||
attr,
|
||||
config,
|
||||
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> {
|
||||
let path = dbus_path_for_attr(self.attr.name());
|
||||
connection
|
||||
@@ -87,7 +64,7 @@ impl AsusArmouryAttribute {
|
||||
|
||||
async fn watch_and_notify(
|
||||
&mut self,
|
||||
signal_ctxt: SignalEmitter<'static>,
|
||||
signal_ctxt: SignalEmitter<'static>
|
||||
) -> Result<(), RogError> {
|
||||
use futures_util::StreamExt;
|
||||
|
||||
@@ -101,27 +78,21 @@ impl AsusArmouryAttribute {
|
||||
let sig = signal_ctxt.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
|
||||
stream
|
||||
.for_each(|_| async {
|
||||
debug!("{} changed", name);
|
||||
ctrl.$fn_prop_changed(&sig).await.ok();
|
||||
})
|
||||
.await;
|
||||
} else {
|
||||
info!(
|
||||
"inotify event stream failed for {} ({}). You can ignore this \
|
||||
if unsupported",
|
||||
name, $attr_str
|
||||
);
|
||||
}
|
||||
watch
|
||||
.into_event_stream(&mut buffer)
|
||||
.unwrap()
|
||||
.for_each(|_| async {
|
||||
debug!("{} changed", name);
|
||||
ctrl.$fn_prop_changed(&sig).await.ok();
|
||||
})
|
||||
.await;
|
||||
});
|
||||
}
|
||||
Err(e) => info!(
|
||||
"inotify watch failed: {}. You can ignore this if your device does not \
|
||||
support the feature",
|
||||
e
|
||||
),
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -136,106 +107,35 @@ impl AsusArmouryAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ArmouryAttributeRegistry {
|
||||
attrs: Vec<AsusArmouryAttribute>,
|
||||
}
|
||||
|
||||
impl ArmouryAttributeRegistry {
|
||||
pub fn push(&mut self, attr: AsusArmouryAttribute) {
|
||||
self.attrs.push(attr);
|
||||
}
|
||||
|
||||
pub async fn emit_limits(&self, connection: &Connection) -> Result<(), RogError> {
|
||||
let mut last_err: Option<RogError> = None;
|
||||
for attr in &self.attrs {
|
||||
if let Err(e) = attr.emit_limits(connection).await {
|
||||
error!(
|
||||
"Failed to emit updated limits for attribute '{}': {e:?}",
|
||||
attr.attribute_name()
|
||||
);
|
||||
last_err = Some(e);
|
||||
}
|
||||
}
|
||||
if let Some(err) = last_err {
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Reloadable for AsusArmouryAttribute {
|
||||
async fn reload(&mut self) -> Result<(), RogError> {
|
||||
info!("Reloading {}", self.attr.name());
|
||||
let name: FirmwareAttribute = self.attr.name().into();
|
||||
|
||||
// Treat dGPU attributes the same as PPT attributes for power-profile
|
||||
// behaviour so they follow AC/DC tuning groups.
|
||||
if name.is_ppt() || name.is_dgpu() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default()
|
||||
== 1;
|
||||
|
||||
let apply_value = {
|
||||
let config = self.config.lock().await;
|
||||
config
|
||||
.select_tunings_ref(power_plugged, profile)
|
||||
.and_then(|tuning| {
|
||||
if tuning.enabled {
|
||||
tuning.group.get(&self.name()).copied()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(tune) = apply_value {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(tune))
|
||||
.map_err(|e| {
|
||||
error!("Could not set {} value: {e:?}", self.attr.name());
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
info!(
|
||||
"Restored PPT armoury setting {} to {:?}",
|
||||
self.attr.name(),
|
||||
tune
|
||||
);
|
||||
} else {
|
||||
info!("Ignored restoring PPT armoury setting {} as tuning group is disabled or no saved value", self.attr.name());
|
||||
}
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let config = if power_plugged == 1 {
|
||||
&self.config.lock().await.ac_profile_tunings
|
||||
} else {
|
||||
// Handle non-PPT attributes (boolean and other settings)
|
||||
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(*saved_value))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Error restoring armoury setting {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
info!(
|
||||
"Restored armoury setting {} to {:?}",
|
||||
self.attr.name(),
|
||||
saved_value
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"No saved armoury setting for {}: skipping restore",
|
||||
self.attr.name()
|
||||
);
|
||||
&self.config.lock().await.dc_profile_tunings
|
||||
};
|
||||
if let Some(tuning) = config.get(&profile) {
|
||||
if tuning.enabled {
|
||||
if let Some(tune) = tuning.group.get(&self.name()) {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(*tune))
|
||||
.map_err(|e| {
|
||||
error!("Could not set {} value: {e:?}", self.attr.name());
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
info!("Set {} to {:?}", self.attr.name(), tune);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,13 +187,13 @@ impl AsusArmouryAttribute {
|
||||
async fn default_value(&self) -> i32 {
|
||||
match self.attr.default_value() {
|
||||
AttrValue::Integer(i) => *i,
|
||||
_ => -1,
|
||||
_ => -1
|
||||
}
|
||||
}
|
||||
|
||||
async fn restore_default(&self) -> fdo::Result<()> {
|
||||
self.attr.restore_default()?;
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
if self.name().is_ppt() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
@@ -326,33 +226,39 @@ impl AsusArmouryAttribute {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn min_value(&self) -> i32 {
|
||||
Self::resolve_i32_value(self.attr.refresh_min_value(), self.attr.min_value())
|
||||
match self.attr.min_value() {
|
||||
AttrValue::Integer(i) => *i,
|
||||
_ => -1
|
||||
}
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn max_value(&self) -> i32 {
|
||||
Self::resolve_i32_value(self.attr.refresh_max_value(), self.attr.max_value())
|
||||
match self.attr.max_value() {
|
||||
AttrValue::Integer(i) => *i,
|
||||
_ => -1
|
||||
}
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn scalar_increment(&self) -> i32 {
|
||||
Self::resolve_i32_value(
|
||||
self.attr.refresh_scalar_increment(),
|
||||
self.attr.scalar_increment(),
|
||||
)
|
||||
match self.attr.scalar_increment() {
|
||||
AttrValue::Integer(i) => *i,
|
||||
_ => -1
|
||||
}
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn possible_values(&self) -> Vec<i32> {
|
||||
match self.attr.possible_values() {
|
||||
AttrValue::EnumInt(i) => i.clone(),
|
||||
_ => Vec::default(),
|
||||
_ => Vec::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn current_value(&self) -> fdo::Result<i32> {
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
if self.name().is_ppt() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
@@ -361,19 +267,16 @@ impl AsusArmouryAttribute {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default()
|
||||
== 1;
|
||||
let config = self.config.lock().await;
|
||||
if let Some(tuning) = config.select_tunings_ref(power_plugged, profile) {
|
||||
if let Some(tune) = tuning.group.get(&self.name()) {
|
||||
return Ok(*tune);
|
||||
}
|
||||
}
|
||||
if let AttrValue::Integer(i) = self.attr.default_value() {
|
||||
.unwrap_or_default();
|
||||
let mut config = self.config.lock().await;
|
||||
let tuning = config.select_tunings(power_plugged == 1, profile);
|
||||
if let Some(tune) = tuning.group.get(&self.name()) {
|
||||
return Ok(*tune);
|
||||
} else if let AttrValue::Integer(i) = self.attr.default_value() {
|
||||
return Ok(*i);
|
||||
}
|
||||
return Err(fdo::Error::Failed(
|
||||
"Could not read current value".to_string(),
|
||||
"Could not read current value".to_string()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -381,13 +284,13 @@ impl AsusArmouryAttribute {
|
||||
return Ok(i);
|
||||
}
|
||||
Err(fdo::Error::Failed(
|
||||
"Could not read current value".to_string(),
|
||||
"Could not read current value".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
if self.name().is_ppt() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
@@ -411,44 +314,44 @@ impl AsusArmouryAttribute {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(value))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Could not set value to PPT property {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
error!("Could not set value: {e:?}");
|
||||
e
|
||||
})?;
|
||||
} else {
|
||||
warn!(
|
||||
"Tuning group is disabled: skipping setting value to PPT property {}",
|
||||
self.attr.name()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(value))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Could not set value {value} to attribute {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
error!("Could not set value: {e:?}");
|
||||
e
|
||||
})?;
|
||||
|
||||
let mut settings = self.config.lock().await;
|
||||
settings
|
||||
let has_attr = self
|
||||
.config
|
||||
.lock()
|
||||
.await
|
||||
.armoury_settings
|
||||
.entry(self.name())
|
||||
.and_modify(|setting| {
|
||||
debug!("Set config for {} = {value}", self.attr.name());
|
||||
*setting = value;
|
||||
})
|
||||
.or_insert_with(|| {
|
||||
debug!("Adding config for {} = {value}", self.attr.name());
|
||||
value
|
||||
});
|
||||
.contains_key(&self.name());
|
||||
if has_attr {
|
||||
if let Some(setting) = self
|
||||
.config
|
||||
.lock()
|
||||
.await
|
||||
.armoury_settings
|
||||
.get_mut(&self.name())
|
||||
{
|
||||
*setting = value
|
||||
}
|
||||
} else {
|
||||
debug!("Adding config for {}", self.attr.name());
|
||||
self.config
|
||||
.lock()
|
||||
.await
|
||||
.armoury_settings
|
||||
.insert(self.name(), value);
|
||||
debug!("Set config for {} = {:?}", self.attr.name(), value);
|
||||
}
|
||||
}
|
||||
|
||||
// write config after setting value
|
||||
self.config.lock().await.write();
|
||||
Ok(())
|
||||
}
|
||||
@@ -459,63 +362,35 @@ pub async fn start_attributes_zbus(
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
attributes: FirmwareAttributes,
|
||||
config: Arc<Mutex<Config>>,
|
||||
) -> Result<ArmouryAttributeRegistry, RogError> {
|
||||
let mut registry = ArmouryAttributeRegistry::default();
|
||||
config: Arc<Mutex<Config>>
|
||||
) -> Result<(), RogError> {
|
||||
for attr in attributes.attributes() {
|
||||
let mut attr = AsusArmouryAttribute::new(
|
||||
attr.clone(),
|
||||
platform.clone(),
|
||||
power.clone(),
|
||||
config.clone(),
|
||||
config.clone()
|
||||
);
|
||||
attr.reload().await?;
|
||||
|
||||
let registry_attr = attr.clone();
|
||||
let path = dbus_path_for_attr(attr.attr.name());
|
||||
let sig = zbus::object_server::SignalEmitter::new(conn, path)?;
|
||||
attr.watch_and_notify(sig).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);
|
||||
attr.move_to_zbus(conn).await?;
|
||||
}
|
||||
Ok(registry)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_config_or_default(
|
||||
attrs: &FirmwareAttributes,
|
||||
config: &mut Config,
|
||||
power_plugged: bool,
|
||||
profile: PlatformProfile,
|
||||
profile: PlatformProfile
|
||||
) {
|
||||
for attr in attrs.attributes().iter() {
|
||||
let name: FirmwareAttribute = attr.name().into();
|
||||
if name.is_ppt() || name.is_dgpu() {
|
||||
if name.is_ppt() {
|
||||
let tuning = config.select_tunings(power_plugged, profile);
|
||||
if !tuning.enabled {
|
||||
debug!("Tuning group is not enabled, skipping");
|
||||
@@ -545,20 +420,6 @@ pub async fn set_config_or_default(
|
||||
// config.write();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle non-PPT attributes (boolean and other settings)
|
||||
if let Some(saved_value) = config.armoury_settings.get(&name) {
|
||||
attr.set_current_value(&AttrValue::Integer(*saved_value))
|
||||
.map_err(|e| {
|
||||
error!("Failed to set {}: {e}", <&str>::from(name));
|
||||
})
|
||||
.ok();
|
||||
info!(
|
||||
"Restored armoury setting for {} = {:?}",
|
||||
<&str>::from(name),
|
||||
saved_value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use config_traits::{StdConfig, StdConfigLoad};
|
||||
use rog_anime::error::AnimeError;
|
||||
use rog_anime::usb::Brightness;
|
||||
use rog_anime::{
|
||||
ActionData, ActionLoader, AnimTime, Animations, AnimeType, DeviceState, Fade, Vec2,
|
||||
ActionData, ActionLoader, AnimTime, Animations, AnimeType, DeviceState, Fade, Vec2
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -15,14 +15,14 @@ pub struct AniMeConfigCached {
|
||||
pub system: Vec<ActionData>,
|
||||
pub boot: Vec<ActionData>,
|
||||
pub wake: Vec<ActionData>,
|
||||
pub shutdown: Vec<ActionData>,
|
||||
pub shutdown: Vec<ActionData>
|
||||
}
|
||||
|
||||
impl AniMeConfigCached {
|
||||
pub fn init_from_config(
|
||||
&mut self,
|
||||
config: &AniMeConfig,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<(), AnimeError> {
|
||||
let mut sys = Vec::with_capacity(config.system.len());
|
||||
for ani in &config.system {
|
||||
@@ -68,7 +68,7 @@ pub struct AniMeConfig {
|
||||
pub off_when_suspended: bool,
|
||||
pub off_when_lid_closed: bool,
|
||||
pub brightness_on_battery: Brightness,
|
||||
pub builtin_anims: Animations,
|
||||
pub builtin_anims: Animations
|
||||
}
|
||||
|
||||
impl Default for AniMeConfig {
|
||||
@@ -87,7 +87,7 @@ impl Default for AniMeConfig {
|
||||
off_when_suspended: true,
|
||||
off_when_lid_closed: true,
|
||||
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_suspended: config.off_when_suspended,
|
||||
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(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
Duration::from_secs(2)
|
||||
))
|
||||
},
|
||||
],
|
||||
wake: vec![
|
||||
@@ -162,8 +162,8 @@ impl AniMeConfig {
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
Duration::from_secs(2)
|
||||
))
|
||||
},
|
||||
],
|
||||
shutdown: vec![
|
||||
@@ -173,7 +173,7 @@ impl AniMeConfig {
|
||||
angle: 0.0,
|
||||
translation: Vec2::new(3.0, 2.0),
|
||||
brightness: 1.0,
|
||||
time: AnimTime::Infinite,
|
||||
time: AnimTime::Infinite
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
|
||||
@@ -8,15 +8,15 @@ use std::sync::Arc;
|
||||
use std::thread::sleep;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_anime::usb::{
|
||||
pkt_flush, pkt_set_brightness, pkt_set_enable_display, pkt_set_enable_powersave_anim,
|
||||
pkts_for_init, Brightness,
|
||||
pkts_for_init, Brightness
|
||||
};
|
||||
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::usb_raw::USBRaw;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use self::config::{AniMeConfig, AniMeConfigCached};
|
||||
use crate::error::RogError;
|
||||
@@ -30,14 +30,14 @@ pub struct AniMe {
|
||||
// set to force thread to exit
|
||||
thread_exit: Arc<AtomicBool>,
|
||||
// Set to false when the thread exits
|
||||
thread_running: Arc<AtomicBool>,
|
||||
thread_running: Arc<AtomicBool>
|
||||
}
|
||||
|
||||
impl AniMe {
|
||||
pub fn new(
|
||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||
config: Arc<Mutex<AniMeConfig>>,
|
||||
config: Arc<Mutex<AniMeConfig>>
|
||||
) -> Self {
|
||||
Self {
|
||||
hid,
|
||||
@@ -45,13 +45,13 @@ impl AniMe {
|
||||
config,
|
||||
cache: AniMeConfigCached::default(),
|
||||
thread_exit: Arc::new(AtomicBool::new(false)),
|
||||
thread_running: Arc::new(AtomicBool::new(false)),
|
||||
thread_running: Arc::new(AtomicBool::new(false))
|
||||
}
|
||||
}
|
||||
|
||||
/// Will fail if something is already holding the config lock
|
||||
async fn do_init_cache(&mut self) {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
if let Some(mut config) = self.config.try_lock() {
|
||||
if let Err(e) = self.cache.init_from_config(&config, config.anime_type) {
|
||||
error!(
|
||||
"Trying to cache the Anime Config failed, will reset to default config: {e:?}"
|
||||
@@ -106,7 +106,7 @@ impl AniMe {
|
||||
pub async fn set_builtins_enabled(
|
||||
&self,
|
||||
enabled: bool,
|
||||
bright: Brightness,
|
||||
bright: Brightness
|
||||
) -> Result<(), RogError> {
|
||||
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))
|
||||
.await?;
|
||||
|
||||
@@ -5,7 +5,7 @@ use log::{debug, error, warn};
|
||||
use logind_zbus::manager::ManagerProxy;
|
||||
use rog_anime::usb::{
|
||||
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 zbus::object_server::SignalEmitter;
|
||||
@@ -41,7 +41,7 @@ impl AniMeZbus {
|
||||
pub async fn start_tasks(
|
||||
mut self,
|
||||
connection: &Connection,
|
||||
path: OwnedObjectPath,
|
||||
path: OwnedObjectPath
|
||||
) -> Result<(), RogError> {
|
||||
// let task = zbus.clone();
|
||||
self.reload()
|
||||
@@ -69,11 +69,7 @@ impl AniMeZbus {
|
||||
/// it is restarted
|
||||
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
||||
let bright = self.0.config.lock().await.display_brightness;
|
||||
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.set_builtins_enabled(false, bright).await?;
|
||||
self.0.thread_exit.store(true, Ordering::SeqCst);
|
||||
self.0.write_data_buffer(input).await.map_err(|err| {
|
||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||
@@ -85,7 +81,7 @@ impl AniMeZbus {
|
||||
/// Set base brightness level
|
||||
#[zbus(property)]
|
||||
async fn brightness(&self) -> Brightness {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.display_brightness;
|
||||
}
|
||||
Brightness::Off
|
||||
@@ -117,7 +113,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn builtins_enabled(&self) -> bool {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.builtin_anims_enabled;
|
||||
}
|
||||
false
|
||||
@@ -162,7 +158,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn builtin_animations(&self) -> Animations {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.builtin_anims;
|
||||
}
|
||||
Animations::default()
|
||||
@@ -173,7 +169,7 @@ impl AniMeZbus {
|
||||
async fn set_builtin_animations(&self, settings: Animations) {
|
||||
self.0
|
||||
.write_bytes(&pkt_set_builtin_animations(
|
||||
settings.boot, settings.awake, settings.sleep, settings.shutdown,
|
||||
settings.boot, settings.awake, settings.sleep, settings.shutdown
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -195,7 +191,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn enable_display(&self) -> bool {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.display_enabled;
|
||||
}
|
||||
false
|
||||
@@ -218,7 +214,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn off_when_unplugged(&self) -> bool {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.off_when_unplugged;
|
||||
}
|
||||
false
|
||||
@@ -245,7 +241,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn off_when_suspended(&self) -> bool {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.off_when_suspended;
|
||||
}
|
||||
false
|
||||
@@ -261,7 +257,7 @@ impl AniMeZbus {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn off_when_lid_closed(&self) -> bool {
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
return config.off_when_lid_closed;
|
||||
}
|
||||
false
|
||||
@@ -323,7 +319,7 @@ impl crate::CtrlTask for AniMeZbus {
|
||||
|
||||
inner
|
||||
.write_bytes(&pkt_set_enable_display(
|
||||
!(sleeping && config.off_when_suspended),
|
||||
!(sleeping && config.off_when_suspended)
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -334,7 +330,7 @@ impl crate::CtrlTask for AniMeZbus {
|
||||
if config.builtin_anims_enabled {
|
||||
inner
|
||||
.write_bytes(&pkt_set_enable_powersave_anim(
|
||||
!(sleeping && config.off_when_suspended),
|
||||
!(sleeping && config.off_when_suspended)
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -437,7 +433,7 @@ impl crate::CtrlTask for AniMeZbus {
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -464,7 +460,7 @@ impl crate::Reloadable for AniMeZbus {
|
||||
builtin_anims.boot,
|
||||
builtin_anims.awake,
|
||||
builtin_anims.sleep,
|
||||
builtin_anims.shutdown,
|
||||
builtin_anims.shutdown
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use log::{debug, info, warn};
|
||||
use rog_aura::aura_detection::LedSupportData;
|
||||
use rog_aura::keyboard::LaptopAuraPower;
|
||||
use rog_aura::{
|
||||
AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT,
|
||||
AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct AuraConfig {
|
||||
pub multizone_on: bool,
|
||||
pub enabled: LaptopAuraPower,
|
||||
#[serde(skip)]
|
||||
pub per_key_mode_active: bool,
|
||||
pub per_key_mode_active: bool
|
||||
}
|
||||
|
||||
impl StdConfig for AuraConfig {
|
||||
@@ -74,7 +74,7 @@ impl AuraConfig {
|
||||
multizone: None,
|
||||
multizone_on: false,
|
||||
enabled,
|
||||
per_key_mode_active: false,
|
||||
per_key_mode_active: false
|
||||
};
|
||||
|
||||
for n in &config.support_data.basic_modes {
|
||||
@@ -82,9 +82,8 @@ impl AuraConfig {
|
||||
config
|
||||
.builtins
|
||||
.insert(*n, AuraEffect::default_with_mode(*n));
|
||||
}
|
||||
if !config.support_data.basic_zones.is_empty() {
|
||||
for n in &config.support_data.basic_modes {
|
||||
|
||||
if !config.support_data.basic_zones.is_empty() {
|
||||
let mut default = vec![];
|
||||
for (i, tmp) in config.support_data.basic_zones.iter().enumerate() {
|
||||
default.push(AuraEffect {
|
||||
@@ -93,7 +92,7 @@ impl AuraConfig {
|
||||
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
||||
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Left,
|
||||
direction: Direction::Left
|
||||
});
|
||||
}
|
||||
if let Some(m) = config.multizone.as_mut() {
|
||||
@@ -119,14 +118,14 @@ impl AuraConfig {
|
||||
self.multizone_on = false;
|
||||
} else {
|
||||
if let Some(multi) = self.multizone.as_mut() {
|
||||
if let Some(fx_vec) = multi.get_mut(effect.mode()) {
|
||||
for fx in fx_vec.iter_mut() {
|
||||
if let Some(fx) = multi.get_mut(effect.mode()) {
|
||||
for fx in fx.iter_mut() {
|
||||
if fx.zone == effect.zone {
|
||||
*fx = effect;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fx_vec.push(effect);
|
||||
fx.push(effect);
|
||||
} else {
|
||||
multi.insert(*effect.mode(), vec![effect]);
|
||||
}
|
||||
@@ -157,7 +156,7 @@ impl AuraConfig {
|
||||
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
||||
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Left,
|
||||
direction: Direction::Left
|
||||
});
|
||||
}
|
||||
if default.is_empty() {
|
||||
@@ -231,29 +230,15 @@ impl AuraConfig {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||
|
||||
use rog_aura::keyboard::AuraPowerState;
|
||||
use rog_aura::{
|
||||
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed,
|
||||
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed
|
||||
};
|
||||
|
||||
use super::AuraConfig;
|
||||
|
||||
// Global mutex to serialize tests that rely on process-wide environment
|
||||
// variables
|
||||
static TEST_MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
|
||||
|
||||
fn test_lock() -> MutexGuard<'static, ()> {
|
||||
TEST_MUTEX
|
||||
.get_or_init(|| Mutex::new(()))
|
||||
.lock()
|
||||
.expect("TEST_MUTEX poisoned")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_multizone_4key_config() {
|
||||
let _guard = test_lock();
|
||||
std::env::set_var("BOARD_NAME", "");
|
||||
let mut config = AuraConfig::new("19b6");
|
||||
|
||||
@@ -261,7 +246,7 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0xff,
|
||||
b: 0xff
|
||||
},
|
||||
zone: AuraZone::Key1,
|
||||
..Default::default()
|
||||
@@ -274,7 +259,7 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0xff,
|
||||
b: 0xff
|
||||
},
|
||||
zone: AuraZone::Key2,
|
||||
..Default::default()
|
||||
@@ -285,7 +270,7 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0xff,
|
||||
g: 0xff,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
},
|
||||
zone: AuraZone::Key3,
|
||||
..Default::default()
|
||||
@@ -296,7 +281,7 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
},
|
||||
zone: AuraZone::Key4,
|
||||
..Default::default()
|
||||
@@ -309,43 +294,30 @@ mod tests {
|
||||
let res = config.multizone.unwrap();
|
||||
let sta = res.get(&AuraModeNum::Static).unwrap();
|
||||
assert_eq!(sta.len(), 4);
|
||||
assert_eq!(
|
||||
sta[0].colour1,
|
||||
Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0xff
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
sta[1].colour1,
|
||||
Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0xff
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
sta[2].colour1,
|
||||
Colour {
|
||||
r: 0xff,
|
||||
g: 0xff,
|
||||
b: 0x00
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
sta[3].colour1,
|
||||
Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0x00
|
||||
}
|
||||
);
|
||||
assert_eq!(sta[0].colour1, Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0xff
|
||||
});
|
||||
assert_eq!(sta[1].colour1, Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0xff
|
||||
});
|
||||
assert_eq!(sta[2].colour1, Colour {
|
||||
r: 0xff,
|
||||
g: 0xff,
|
||||
b: 0x00
|
||||
});
|
||||
assert_eq!(sta[3].colour1, Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0x00
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_multizone_multimode_config() {
|
||||
let _guard = test_lock();
|
||||
std::env::set_var("BOARD_NAME", "");
|
||||
let mut config = AuraConfig::new("19b6");
|
||||
|
||||
@@ -394,65 +366,51 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn verify_0x1866_g531i() {
|
||||
let _guard = test_lock();
|
||||
std::env::set_var("BOARD_NAME", "G513I");
|
||||
let mut config = AuraConfig::new("1866");
|
||||
|
||||
assert_eq!(config.brightness, LedBrightness::Med);
|
||||
assert_eq!(config.builtins.len(), 5);
|
||||
assert_eq!(
|
||||
config.builtins.first_entry().unwrap().get(),
|
||||
&AuraEffect {
|
||||
mode: AuraModeNum::Static,
|
||||
zone: AuraZone::None,
|
||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right
|
||||
}
|
||||
);
|
||||
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect {
|
||||
mode: AuraModeNum::Static,
|
||||
zone: AuraZone::None,
|
||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right
|
||||
});
|
||||
assert_eq!(config.enabled.states.len(), 1);
|
||||
assert_eq!(
|
||||
config.enabled.states[0],
|
||||
AuraPowerState {
|
||||
zone: PowerZones::KeyboardAndLightbar,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true
|
||||
}
|
||||
);
|
||||
assert_eq!(config.enabled.states[0], AuraPowerState {
|
||||
zone: PowerZones::KeyboardAndLightbar,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_0x19b6_g634j() {
|
||||
let _guard = test_lock();
|
||||
std::env::set_var("BOARD_NAME", "G634J");
|
||||
let mut config = AuraConfig::new("19b6");
|
||||
|
||||
assert_eq!(config.brightness, LedBrightness::Med);
|
||||
assert_eq!(config.builtins.len(), 12);
|
||||
assert_eq!(
|
||||
config.builtins.first_entry().unwrap().get(),
|
||||
&AuraEffect {
|
||||
mode: AuraModeNum::Static,
|
||||
zone: AuraZone::None,
|
||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right
|
||||
}
|
||||
);
|
||||
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect {
|
||||
mode: AuraModeNum::Static,
|
||||
zone: AuraZone::None,
|
||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right
|
||||
});
|
||||
assert_eq!(config.enabled.states.len(), 4);
|
||||
assert_eq!(
|
||||
config.enabled.states[0],
|
||||
AuraPowerState {
|
||||
zone: PowerZones::Keyboard,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true
|
||||
}
|
||||
);
|
||||
assert_eq!(config.enabled.states[0], AuraPowerState {
|
||||
zone: PowerZones::Keyboard,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ use std::sync::Arc;
|
||||
|
||||
use config::AuraConfig;
|
||||
use config_traits::StdConfig;
|
||||
use futures_util::lock::{Mutex, MutexGuard};
|
||||
use log::info;
|
||||
use rog_aura::keyboard::{AuraLaptopUsbPackets, LedUsbPackets};
|
||||
use rog_aura::usb::{AURA_LAPTOP_LED_APPLY, AURA_LAPTOP_LED_SET};
|
||||
use rog_aura::{AuraDeviceType, AuraEffect, LedBrightness, PowerZones, AURA_LAPTOP_LED_MSG_LEN};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
use crate::error::RogError;
|
||||
|
||||
@@ -19,7 +19,7 @@ pub mod trait_impls;
|
||||
pub struct Aura {
|
||||
pub hid: Option<Arc<Mutex<HidRaw>>>,
|
||||
pub backlight: Option<Arc<Mutex<KeyboardBacklight>>>,
|
||||
pub config: Arc<Mutex<AuraConfig>>,
|
||||
pub config: Arc<Mutex<AuraConfig>>
|
||||
}
|
||||
|
||||
impl Aura {
|
||||
@@ -28,7 +28,7 @@ impl Aura {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn lock_config(&self) -> MutexGuard<'_, AuraConfig> {
|
||||
pub async fn lock_config(&self) -> MutexGuard<AuraConfig> {
|
||||
self.config.lock().await
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ impl Aura {
|
||||
pub async fn write_effect_and_apply(
|
||||
&self,
|
||||
dev_type: AuraDeviceType,
|
||||
mode: &AuraEffect,
|
||||
mode: &AuraEffect
|
||||
) -> Result<(), RogError> {
|
||||
if matches!(dev_type, AuraDeviceType::LaptopKeyboardTuf) {
|
||||
if let Some(platform) = &self.backlight {
|
||||
let buf = [
|
||||
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)?;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ impl Aura {
|
||||
return Ok(());
|
||||
}
|
||||
Err(RogError::MissingFunction(
|
||||
"No LED backlight control available".to_string(),
|
||||
"No LED backlight control available".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ impl Aura {
|
||||
0x01,
|
||||
p.new_to_byte() as u8,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0
|
||||
];
|
||||
hid_raw.write_bytes(&msg)?;
|
||||
return Ok(());
|
||||
@@ -154,7 +154,7 @@ impl Aura {
|
||||
|
||||
let bytes = config.enabled.to_bytes(config.led_type);
|
||||
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)?;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ impl Aura {
|
||||
pub async fn write_effect_block(
|
||||
&self,
|
||||
config: &mut AuraConfig,
|
||||
effect: &AuraLaptopUsbPackets,
|
||||
effect: &AuraLaptopUsbPackets
|
||||
) -> Result<(), RogError> {
|
||||
if config.brightness == LedBrightness::Off {
|
||||
config.brightness = LedBrightness::Med;
|
||||
@@ -201,7 +201,7 @@ impl Aura {
|
||||
let g = row[10];
|
||||
let b = row[11];
|
||||
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;
|
||||
if config.ally_fix.is_none() {
|
||||
let msg = [
|
||||
0x5d, 0xbd, 0x01, 0xff, 0xff, 0xff, 0xff,
|
||||
0x5d, 0xbd, 0x01, 0xff, 0xff, 0xff, 0xff
|
||||
];
|
||||
hid_raw.lock().await.write_bytes(&msg)?;
|
||||
info!("Reset Ally power settings to base");
|
||||
|
||||
@@ -28,7 +28,7 @@ impl AuraZbus {
|
||||
mut self,
|
||||
connection: &Connection,
|
||||
// _signal_ctx: SignalEmitter<'static>,
|
||||
path: OwnedObjectPath,
|
||||
path: OwnedObjectPath
|
||||
) -> Result<(), RogError> {
|
||||
// let task = zbus.clone();
|
||||
// let signal_ctx = signal_ctx.clone();
|
||||
@@ -71,13 +71,7 @@ impl AuraZbus {
|
||||
#[zbus(property)]
|
||||
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
||||
if let Some(bl) = self.0.backlight.as_ref() {
|
||||
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?);
|
||||
return Ok(bl.lock().await.set_brightness(brightness.into())?);
|
||||
}
|
||||
Err(ZbErr::Failed("No sysfs brightness control".to_string()))
|
||||
}
|
||||
@@ -118,7 +112,7 @@ impl AuraZbus {
|
||||
// entirely possible to deadlock here, so use try instead of lock()
|
||||
// let ctrl = self.0.lock().await;
|
||||
// Ok(config.current_mode)
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
Ok(config.current_mode)
|
||||
} else {
|
||||
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||
@@ -146,11 +140,11 @@ impl AuraZbus {
|
||||
#[zbus(property)]
|
||||
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||
// entirely possible to deadlock here, so use try instead of lock()
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
let mode = config.current_mode;
|
||||
match config.builtins.get(&mode) {
|
||||
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 {
|
||||
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||
@@ -303,7 +297,7 @@ impl CtrlTask for AuraZbus {
|
||||
move |_power_plugged| {
|
||||
// power change
|
||||
async move {}
|
||||
},
|
||||
}
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
// - Add it to Zbus server
|
||||
// - If udev sees device removed then remove the zbus path
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use dmi_id::DMIID;
|
||||
use futures_lite::future::block_on;
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info, warn};
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use rog_platform::error::PlatformError;
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use tokio::sync::Mutex;
|
||||
use udev::{Device, MonitorBuilder};
|
||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
|
||||
use zbus::Connection;
|
||||
@@ -57,7 +56,7 @@ fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
|
||||
if let Some(filename) = filename_partial(parent) {
|
||||
return Some(
|
||||
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{filename}"))
|
||||
.into(),
|
||||
.into()
|
||||
);
|
||||
}
|
||||
None
|
||||
@@ -92,47 +91,24 @@ fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
|
||||
/// required.
|
||||
pub struct AsusDevice {
|
||||
device: DeviceHandle,
|
||||
dbus_path: OwnedObjectPath,
|
||||
hid_key: Option<String>,
|
||||
dbus_path: OwnedObjectPath
|
||||
}
|
||||
|
||||
pub struct DeviceManager {
|
||||
_dbus_connection: Connection,
|
||||
_hid_handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||
_dbus_connection: Connection
|
||||
}
|
||||
|
||||
impl DeviceManager {
|
||||
#[allow(clippy::type_complexity)]
|
||||
async fn get_or_create_hid_handle(
|
||||
handles: &Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||
endpoint: &Device,
|
||||
) -> Result<(Arc<Mutex<HidRaw>>, String), RogError> {
|
||||
let dev_node = endpoint
|
||||
.devnode()
|
||||
.ok_or_else(|| RogError::MissingFunction("hidraw devnode missing".to_string()))?;
|
||||
let key = dev_node.to_string_lossy().to_string();
|
||||
|
||||
if let Some(existing) = handles.lock().await.get(&key).cloned() {
|
||||
return Ok((existing, key));
|
||||
}
|
||||
|
||||
let hidraw = HidRaw::from_device(endpoint.clone())?;
|
||||
let handle = Arc::new(Mutex::new(hidraw));
|
||||
handles.lock().await.insert(key.clone(), handle.clone());
|
||||
Ok((handle, key))
|
||||
}
|
||||
|
||||
async fn init_hid_devices(
|
||||
connection: &Connection,
|
||||
device: Device,
|
||||
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||
device: Device
|
||||
) -> Result<Vec<AsusDevice>, RogError> {
|
||||
let mut devices = Vec::new();
|
||||
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||
if let Some(vendor_id) = usb_device.attribute_value("idVendor") {
|
||||
if vendor_id != "0b05" {
|
||||
debug!("Not ASUS vendor ID: {}", vendor_id.to_string_lossy());
|
||||
debug!("Not ASUS vendor ID");
|
||||
return Ok(devices);
|
||||
}
|
||||
// Almost all devices are identified by the productId.
|
||||
@@ -140,14 +116,13 @@ impl DeviceManager {
|
||||
// 1. Generate an interface path
|
||||
// 2. Create the device
|
||||
// Use the top-level endpoint, not the parent
|
||||
if let Ok((dev, hid_key)) =
|
||||
Self::get_or_create_hid_handle(&handles, &device).await
|
||||
{
|
||||
if let Ok(hidraw) = HidRaw::from_device(device) {
|
||||
debug!("Testing device {usb_id:?}");
|
||||
let dev = Arc::new(Mutex::new(hidraw));
|
||||
// SLASH DEVICE
|
||||
if let Ok(dev_type) = DeviceHandle::new_slash_hid(
|
||||
dev.clone(),
|
||||
usb_id.to_str().unwrap_or_default(),
|
||||
usb_id.to_str().unwrap_or_default()
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -158,15 +133,14 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: Some(hid_key.clone()),
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
// ANIME MATRIX DEVICE
|
||||
if let Ok(dev_type) = DeviceHandle::maybe_anime_hid(
|
||||
dev.clone(),
|
||||
usb_id.to_str().unwrap_or_default(),
|
||||
usb_id.to_str().unwrap_or_default()
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -177,15 +151,14 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: Some(hid_key.clone()),
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
// AURA LAPTOP DEVICE
|
||||
if let Ok(dev_type) = DeviceHandle::maybe_laptop_aura(
|
||||
Some(dev),
|
||||
usb_id.to_str().unwrap_or_default(),
|
||||
usb_id.to_str().unwrap_or_default()
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -196,13 +169,10 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: Some(hid_key),
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Failed to initialise shared hid handle for {usb_id:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,10 +181,7 @@ impl DeviceManager {
|
||||
}
|
||||
|
||||
/// To be called on daemon startup
|
||||
async fn init_all_hid(
|
||||
connection: &Connection,
|
||||
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||
) -> Result<Vec<AsusDevice>, RogError> {
|
||||
async fn init_all_hid(connection: &Connection) -> Result<Vec<AsusDevice>, RogError> {
|
||||
// track and ensure we use only one hidraw per prod_id
|
||||
// let mut interfaces = HashSet::new();
|
||||
let mut devices: Vec<AsusDevice> = Vec::new();
|
||||
@@ -233,7 +200,7 @@ impl DeviceManager {
|
||||
.scan_devices()
|
||||
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
|
||||
{
|
||||
devices.append(&mut Self::init_hid_devices(connection, device, handles.clone()).await?);
|
||||
devices.append(&mut Self::init_hid_devices(connection, device).await?);
|
||||
}
|
||||
|
||||
Ok(devices)
|
||||
@@ -242,7 +209,7 @@ impl DeviceManager {
|
||||
async fn init_scsi(
|
||||
connection: &Connection,
|
||||
device: &Device,
|
||||
path: OwnedObjectPath,
|
||||
path: OwnedObjectPath
|
||||
) -> Option<AsusDevice> {
|
||||
// "ID_MODEL_ID" "1932"
|
||||
// "ID_VENDOR_ID" "0b05"
|
||||
@@ -260,8 +227,7 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
return Some(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: None,
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -309,13 +275,10 @@ impl DeviceManager {
|
||||
Ok(devices)
|
||||
}
|
||||
|
||||
pub async fn find_all_devices(
|
||||
connection: &Connection,
|
||||
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||
) -> Vec<AsusDevice> {
|
||||
pub async fn find_all_devices(connection: &Connection) -> Vec<AsusDevice> {
|
||||
let mut devices: Vec<AsusDevice> = Vec::new();
|
||||
// HID first, always
|
||||
if let Ok(devs) = &mut Self::init_all_hid(connection, handles.clone()).await {
|
||||
if let Ok(devs) = &mut Self::init_all_hid(connection).await {
|
||||
devices.append(devs);
|
||||
}
|
||||
// USB after, need to check if HID picked something up and if so, skip it
|
||||
@@ -342,8 +305,7 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: None,
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -365,8 +327,7 @@ impl DeviceManager {
|
||||
{
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: None,
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -393,8 +354,7 @@ impl DeviceManager {
|
||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||
devices.push(AsusDevice {
|
||||
device: dev_type,
|
||||
dbus_path: path,
|
||||
hid_key: None,
|
||||
dbus_path: path
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -410,19 +370,16 @@ impl DeviceManager {
|
||||
|
||||
pub async fn new(connection: Connection) -> Result<Self, RogError> {
|
||||
let conn_copy = connection.clone();
|
||||
let hid_handles = Arc::new(Mutex::new(HashMap::new()));
|
||||
let devices = Self::find_all_devices(&conn_copy, hid_handles.clone()).await;
|
||||
let devices = Self::find_all_devices(&conn_copy).await;
|
||||
info!("Found {} valid devices on startup", devices.len());
|
||||
let devices = Arc::new(Mutex::new(devices));
|
||||
let manager = Self {
|
||||
_dbus_connection: connection,
|
||||
_hid_handles: hid_handles.clone(),
|
||||
_dbus_connection: connection
|
||||
};
|
||||
|
||||
// TODO: The /sysfs/ LEDs don't cause events, so they need to be manually
|
||||
// checked for and added
|
||||
|
||||
let hid_handles_thread = hid_handles.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut monitor = MonitorBuilder::new()?.listen()?;
|
||||
let mut poll = Poll::new()?;
|
||||
@@ -451,7 +408,6 @@ impl DeviceManager {
|
||||
|
||||
let devices = devices.clone();
|
||||
let conn_copy = conn_copy.clone();
|
||||
let hid_handles = hid_handles_thread.clone();
|
||||
block_on(async move {
|
||||
// SCSCI devs
|
||||
if subsys == "block" {
|
||||
@@ -527,7 +483,6 @@ impl DeviceManager {
|
||||
// Iter in reverse so as to not screw up indexing
|
||||
for index in removals.iter().rev() {
|
||||
let dev = devices.lock().await.remove(*index);
|
||||
let hid_key = dev.hid_key.clone();
|
||||
let path = path.clone();
|
||||
let res = match dev.device {
|
||||
DeviceHandle::Aura(_) => {
|
||||
@@ -554,23 +509,17 @@ impl DeviceManager {
|
||||
.remove::<ScsiZbus, _>(&path)
|
||||
.await?
|
||||
}
|
||||
_ => todo!(),
|
||||
_ => todo!()
|
||||
};
|
||||
info!("AuraManager removed: {path:?}, {res}");
|
||||
if let Some(key) = hid_key {
|
||||
hid_handles.lock().await.remove(&key);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if action == "add" {
|
||||
let evdev = event.device();
|
||||
if let Ok(mut new_devs) = Self::init_hid_devices(
|
||||
&conn_copy,
|
||||
evdev,
|
||||
hid_handles.clone(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
||||
if let Ok(mut new_devs) =
|
||||
Self::init_hid_devices(&conn_copy, evdev)
|
||||
.await
|
||||
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
||||
{
|
||||
devices.lock().await.append(&mut new_devs);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct ScsiConfig {
|
||||
pub dev_type: AuraDeviceType,
|
||||
pub enabled: bool,
|
||||
pub current_mode: AuraMode,
|
||||
pub modes: BTreeMap<AuraMode, AuraEffect>,
|
||||
pub modes: BTreeMap<AuraMode, AuraEffect>
|
||||
}
|
||||
|
||||
impl ScsiConfig {
|
||||
@@ -38,61 +38,61 @@ impl Default for ScsiConfig {
|
||||
(AuraMode::Off, AuraEffect::default_with_mode(AuraMode::Off)),
|
||||
(
|
||||
AuraMode::Static,
|
||||
AuraEffect::default_with_mode(AuraMode::Static),
|
||||
AuraEffect::default_with_mode(AuraMode::Static)
|
||||
),
|
||||
(
|
||||
AuraMode::Breathe,
|
||||
AuraEffect::default_with_mode(AuraMode::Breathe),
|
||||
AuraEffect::default_with_mode(AuraMode::Breathe)
|
||||
),
|
||||
(
|
||||
AuraMode::Flashing,
|
||||
AuraEffect::default_with_mode(AuraMode::Flashing),
|
||||
AuraEffect::default_with_mode(AuraMode::Flashing)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowCycle,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycle),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycle)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowWave,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowWave),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowWave)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowCycleBreathe,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleBreathe),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleBreathe)
|
||||
),
|
||||
(
|
||||
AuraMode::ChaseFade,
|
||||
AuraEffect::default_with_mode(AuraMode::ChaseFade),
|
||||
AuraEffect::default_with_mode(AuraMode::ChaseFade)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowCycleChaseFade,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChaseFade),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChaseFade)
|
||||
),
|
||||
(
|
||||
AuraMode::Chase,
|
||||
AuraEffect::default_with_mode(AuraMode::Chase),
|
||||
AuraEffect::default_with_mode(AuraMode::Chase)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowCycleChase,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChase),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChase)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowCycleWave,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleWave),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleWave)
|
||||
),
|
||||
(
|
||||
AuraMode::RainbowPulseChase,
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowPulseChase),
|
||||
AuraEffect::default_with_mode(AuraMode::RainbowPulseChase)
|
||||
),
|
||||
(
|
||||
AuraMode::RandomFlicker,
|
||||
AuraEffect::default_with_mode(AuraMode::RandomFlicker),
|
||||
AuraEffect::default_with_mode(AuraMode::RandomFlicker)
|
||||
),
|
||||
(
|
||||
AuraMode::DoubleFade,
|
||||
AuraEffect::default_with_mode(AuraMode::DoubleFade),
|
||||
),
|
||||
]),
|
||||
AuraEffect::default_with_mode(AuraMode::DoubleFade)
|
||||
)
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use config::ScsiConfig;
|
||||
use futures_util::lock::{Mutex, MutexGuard};
|
||||
use rog_scsi::{AuraEffect, Device, Task};
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
use crate::error::RogError;
|
||||
|
||||
@@ -12,7 +12,7 @@ pub mod trait_impls;
|
||||
#[derive(Clone)]
|
||||
pub struct ScsiAura {
|
||||
device: Arc<Mutex<Device>>,
|
||||
config: Arc<Mutex<ScsiConfig>>,
|
||||
config: Arc<Mutex<ScsiConfig>>
|
||||
}
|
||||
|
||||
impl ScsiAura {
|
||||
@@ -20,7 +20,7 @@ impl ScsiAura {
|
||||
Self { device, config }
|
||||
}
|
||||
|
||||
pub async fn lock_config(&self) -> MutexGuard<'_, ScsiConfig> {
|
||||
pub async fn lock_config(&self) -> MutexGuard<ScsiConfig> {
|
||||
self.config.lock().await
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ impl ScsiZbus {
|
||||
pub async fn start_tasks(
|
||||
self,
|
||||
connection: &Connection,
|
||||
path: OwnedObjectPath,
|
||||
path: OwnedObjectPath
|
||||
) -> Result<(), RogError> {
|
||||
connection
|
||||
.object_server()
|
||||
@@ -83,11 +83,11 @@ impl ScsiZbus {
|
||||
#[zbus(property)]
|
||||
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||
// entirely possible to deadlock here, so use try instead of lock()
|
||||
if let Ok(config) = self.0.config.try_lock() {
|
||||
if let Some(config) = self.0.config.try_lock() {
|
||||
let mode = config.current_mode;
|
||||
match config.modes.get(&mode) {
|
||||
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 {
|
||||
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||
|
||||
@@ -17,8 +17,7 @@ pub struct SlashConfig {
|
||||
pub show_on_shutdown: bool,
|
||||
pub show_on_sleep: bool,
|
||||
pub show_on_battery: bool,
|
||||
pub show_battery_warning: bool,
|
||||
pub show_on_lid_closed: bool,
|
||||
pub show_battery_warning: bool
|
||||
}
|
||||
|
||||
impl Default for SlashConfig {
|
||||
@@ -33,8 +32,7 @@ impl Default for SlashConfig {
|
||||
show_on_shutdown: true,
|
||||
show_on_sleep: true,
|
||||
show_on_battery: true,
|
||||
show_battery_warning: true,
|
||||
show_on_lid_closed: true,
|
||||
show_battery_warning: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +58,7 @@ impl From<&SlashConfig> for DeviceState {
|
||||
slash_enabled: config.enabled,
|
||||
slash_brightness: config.brightness,
|
||||
slash_interval: config.display_interval,
|
||||
slash_mode: config.display_mode,
|
||||
slash_mode: config.display_mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use config::SlashConfig;
|
||||
use futures_util::lock::{Mutex, MutexGuard};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::usb_raw::USBRaw;
|
||||
use rog_slash::usb::{slash_pkt_enable, slash_pkt_init, slash_pkt_options, slash_pkt_set_mode};
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
use rog_slash::usb::{get_options_packet, pkt_set_mode, pkts_for_init};
|
||||
use rog_slash::SlashType;
|
||||
|
||||
use crate::error::RogError;
|
||||
|
||||
@@ -15,19 +16,19 @@ pub mod trait_impls;
|
||||
pub struct Slash {
|
||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||
config: Arc<Mutex<SlashConfig>>,
|
||||
config: Arc<Mutex<SlashConfig>>
|
||||
}
|
||||
|
||||
impl Slash {
|
||||
pub fn new(
|
||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||
config: Arc<Mutex<SlashConfig>>,
|
||||
config: Arc<Mutex<SlashConfig>>
|
||||
) -> Self {
|
||||
Self { hid, usb, config }
|
||||
}
|
||||
|
||||
pub async fn lock_config(&self) -> MutexGuard<'_, SlashConfig> {
|
||||
pub async fn lock_config(&self) -> MutexGuard<SlashConfig> {
|
||||
self.config.lock().await
|
||||
}
|
||||
|
||||
@@ -45,22 +46,22 @@ impl Slash {
|
||||
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
||||
// Don't try to initialise these models as the asus drivers already did
|
||||
let config = self.config.lock().await;
|
||||
for pkt in &slash_pkt_init(config.slash_type) {
|
||||
self.write_bytes(pkt).await?;
|
||||
if !matches!(config.slash_type, SlashType::GA605 | SlashType::GU605) {
|
||||
for pkt in &pkts_for_init(config.slash_type) {
|
||||
self.write_bytes(pkt).await?;
|
||||
}
|
||||
}
|
||||
self.write_bytes(&slash_pkt_enable(config.slash_type, config.enabled))
|
||||
.await?;
|
||||
|
||||
// Apply config upon initialization
|
||||
let option_packets = slash_pkt_options(
|
||||
let option_packets = get_options_packet(
|
||||
config.slash_type,
|
||||
config.enabled,
|
||||
config.brightness,
|
||||
config.display_interval,
|
||||
config.display_interval
|
||||
);
|
||||
self.write_bytes(&option_packets).await?;
|
||||
|
||||
let mode_packets = slash_pkt_set_mode(config.slash_type, config.display_mode);
|
||||
let mode_packets = pkt_set_mode(config.slash_type, config.display_mode);
|
||||
// self.node.write_bytes(&mode_packets[0])?;
|
||||
self.write_bytes(&mode_packets[1]).await?;
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use config_traits::StdConfig;
|
||||
use log::{debug, error, warn};
|
||||
use rog_slash::usb::{
|
||||
slash_pkt_battery_saver, slash_pkt_boot, slash_pkt_enable, slash_pkt_lid_closed,
|
||||
slash_pkt_low_battery, slash_pkt_options, slash_pkt_save, slash_pkt_set_mode,
|
||||
slash_pkt_shutdown, slash_pkt_sleep,
|
||||
get_battery_saver_packet, get_boot_packet, get_low_battery_packet, get_options_packet,
|
||||
get_shutdown_packet, get_sleep_packet, pkt_save, pkt_set_mode
|
||||
};
|
||||
use rog_slash::{DeviceState, SlashMode};
|
||||
use zbus::zvariant::OwnedObjectPath;
|
||||
@@ -24,7 +23,7 @@ impl SlashZbus {
|
||||
pub async fn start_tasks(
|
||||
mut self,
|
||||
connection: &Connection,
|
||||
path: OwnedObjectPath,
|
||||
path: OwnedObjectPath
|
||||
) -> Result<(), RogError> {
|
||||
// let task = zbus.clone();
|
||||
self.reload()
|
||||
@@ -59,18 +58,11 @@ impl SlashZbus {
|
||||
config.brightness
|
||||
};
|
||||
self.0
|
||||
.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(
|
||||
.write_bytes(&get_options_packet(
|
||||
config.slash_type,
|
||||
enabled,
|
||||
brightness,
|
||||
config.display_interval,
|
||||
config.display_interval
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -96,11 +88,11 @@ impl SlashZbus {
|
||||
let mut config = self.0.lock_config().await;
|
||||
let enabled = brightness > 0;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_options(
|
||||
.write_bytes(&get_options_packet(
|
||||
config.slash_type,
|
||||
enabled,
|
||||
brightness,
|
||||
config.display_interval,
|
||||
config.display_interval
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -124,8 +116,8 @@ impl SlashZbus {
|
||||
async fn set_interval(&self, interval: u8) {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_options(
|
||||
config.slash_type, config.enabled, config.brightness, interval,
|
||||
.write_bytes(&get_options_packet(
|
||||
config.slash_type, config.enabled, config.brightness, interval
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -148,12 +140,10 @@ impl SlashZbus {
|
||||
async fn set_mode(&self, mode: SlashMode) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
|
||||
let command_packets = slash_pkt_set_mode(config.slash_type, mode);
|
||||
let command_packets = pkt_set_mode(config.slash_type, mode);
|
||||
// self.node.write_bytes(&command_packets[0])?;
|
||||
self.0.write_bytes(&command_packets[1]).await?;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_save(config.slash_type))
|
||||
.await?;
|
||||
self.0.write_bytes(&pkt_save(config.slash_type)).await?;
|
||||
|
||||
config.display_mode = mode;
|
||||
config.write();
|
||||
@@ -177,7 +167,7 @@ impl SlashZbus {
|
||||
async fn set_show_on_boot(&self, enable: bool) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_boot(config.slash_type, enable))
|
||||
.write_bytes(&get_boot_packet(config.slash_type, enable))
|
||||
.await?;
|
||||
config.show_on_boot = enable;
|
||||
config.write();
|
||||
@@ -194,7 +184,7 @@ impl SlashZbus {
|
||||
async fn set_show_on_sleep(&self, enable: bool) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_sleep(config.slash_type, enable))
|
||||
.write_bytes(&get_sleep_packet(config.slash_type, enable))
|
||||
.await?;
|
||||
config.show_on_sleep = enable;
|
||||
config.write();
|
||||
@@ -211,7 +201,7 @@ impl SlashZbus {
|
||||
async fn set_show_on_shutdown(&self, enable: bool) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_shutdown(config.slash_type, enable))
|
||||
.write_bytes(&get_shutdown_packet(config.slash_type, enable))
|
||||
.await?;
|
||||
config.show_on_shutdown = enable;
|
||||
config.write();
|
||||
@@ -228,7 +218,7 @@ impl SlashZbus {
|
||||
async fn set_show_on_battery(&self, enable: bool) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_battery_saver(config.slash_type, enable))
|
||||
.write_bytes(&get_battery_saver_packet(config.slash_type, enable))
|
||||
.await?;
|
||||
config.show_on_battery = enable;
|
||||
config.write();
|
||||
@@ -245,32 +235,12 @@ impl SlashZbus {
|
||||
async fn set_show_battery_warning(&self, enable: bool) -> zbus::Result<()> {
|
||||
let mut config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_low_battery(config.slash_type, enable))
|
||||
.write_bytes(&get_low_battery_packet(config.slash_type, enable))
|
||||
.await?;
|
||||
config.show_battery_warning = enable;
|
||||
config.write();
|
||||
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 {
|
||||
@@ -278,11 +248,11 @@ impl Reloadable for SlashZbus {
|
||||
debug!("reloading slash settings");
|
||||
let config = self.0.lock_config().await;
|
||||
self.0
|
||||
.write_bytes(&slash_pkt_options(
|
||||
.write_bytes(&get_options_packet(
|
||||
config.slash_type,
|
||||
config.enabled,
|
||||
config.brightness,
|
||||
config.display_interval,
|
||||
config.display_interval
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
@@ -302,12 +272,12 @@ impl Reloadable for SlashZbus {
|
||||
};
|
||||
}
|
||||
|
||||
write_bytes_with_warning!(slash_pkt_boot, show_on_boot, "show_on_boot");
|
||||
write_bytes_with_warning!(slash_pkt_sleep, show_on_sleep, "show_on_sleep");
|
||||
write_bytes_with_warning!(slash_pkt_shutdown, show_on_shutdown, "show_on_shutdown");
|
||||
write_bytes_with_warning!(slash_pkt_battery_saver, show_on_battery, "show_on_battery");
|
||||
write_bytes_with_warning!(get_boot_packet, show_on_boot, "show_on_boot");
|
||||
write_bytes_with_warning!(get_sleep_packet, show_on_sleep, "show_on_sleep");
|
||||
write_bytes_with_warning!(get_shutdown_packet, 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_low_battery,
|
||||
get_low_battery_packet,
|
||||
show_battery_warning,
|
||||
"show_battery_warning"
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info};
|
||||
use rog_anime::error::AnimeError;
|
||||
use rog_anime::usb::get_anime_type;
|
||||
@@ -12,7 +13,6 @@ use rog_platform::usb_raw::USBRaw;
|
||||
use rog_scsi::{open_device, ScsiType};
|
||||
use rog_slash::error::SlashError;
|
||||
use rog_slash::SlashType;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::aura_anime::config::AniMeConfig;
|
||||
use crate::aura_anime::AniMe;
|
||||
@@ -31,7 +31,7 @@ pub enum _DeviceHandle {
|
||||
LedClass(KeyboardBacklight),
|
||||
/// TODO
|
||||
MulticolourLed,
|
||||
None,
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -47,14 +47,14 @@ pub enum DeviceHandle {
|
||||
TufLedClass(Arc<Mutex<HidRaw>>),
|
||||
/// TODO
|
||||
MulticolourLed,
|
||||
None,
|
||||
None
|
||||
}
|
||||
|
||||
impl DeviceHandle {
|
||||
/// Try Slash HID. If one exists it is initialsed and returned.
|
||||
pub async fn new_slash_hid(
|
||||
device: Arc<Mutex<HidRaw>>,
|
||||
prod_id: &str,
|
||||
prod_id: &str
|
||||
) -> Result<Self, RogError> {
|
||||
debug!("Testing for HIDRAW Slash");
|
||||
let slash_type = SlashType::from_dmi();
|
||||
@@ -93,7 +93,7 @@ impl DeviceHandle {
|
||||
let slash = Slash::new(
|
||||
None,
|
||||
Some(Arc::new(Mutex::new(usb))),
|
||||
Arc::new(Mutex::new(config)),
|
||||
Arc::new(Mutex::new(config))
|
||||
);
|
||||
slash.do_initialization().await?;
|
||||
Ok(Self::Slash(slash))
|
||||
@@ -105,11 +105,11 @@ impl DeviceHandle {
|
||||
/// Try AniMe Matrix HID. If one exists it is initialsed and returned.
|
||||
pub async fn maybe_anime_hid(
|
||||
_device: Arc<Mutex<HidRaw>>,
|
||||
_prod_id: &str,
|
||||
_prod_id: &str
|
||||
) -> Result<Self, RogError> {
|
||||
// TODO: can't use HIDRAW for anime at the moment
|
||||
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");
|
||||
@@ -144,13 +144,13 @@ impl DeviceHandle {
|
||||
let mut anime = AniMe::new(
|
||||
None,
|
||||
Some(Arc::new(Mutex::new(usb))),
|
||||
Arc::new(Mutex::new(config)),
|
||||
Arc::new(Mutex::new(config))
|
||||
);
|
||||
anime.do_initialization().await?;
|
||||
Ok(Self::AniMe(anime))
|
||||
} else {
|
||||
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(
|
||||
device: Option<Arc<Mutex<HidRaw>>>,
|
||||
prod_id: &str,
|
||||
prod_id: &str
|
||||
) -> Result<Self, RogError> {
|
||||
debug!("Testing for laptop aura");
|
||||
let aura_type = AuraDeviceType::from(prod_id);
|
||||
@@ -201,7 +201,7 @@ impl DeviceHandle {
|
||||
let aura = Aura {
|
||||
hid: device,
|
||||
backlight,
|
||||
config: Arc::new(Mutex::new(config)),
|
||||
config: Arc::new(Mutex::new(config))
|
||||
};
|
||||
aura.do_initialization().await?;
|
||||
Ok(Self::Aura(aura))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad2};
|
||||
use config_traits::{StdConfig, StdConfigLoad1};
|
||||
use rog_platform::asus_armoury::FirmwareAttribute;
|
||||
use rog_platform::cpu::CPUEPP;
|
||||
use rog_platform::platform::PlatformProfile;
|
||||
@@ -8,16 +8,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
const CONFIG_FILE: &str = "asusd.ron";
|
||||
|
||||
/// Default value for base_charge_control_end_threshold when not present in config.
|
||||
/// Returns 0 so restore_charge_limit() skips restoration for upgraded configs.
|
||||
fn default_base_charge_limit() -> u8 {
|
||||
0
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Deserialize, Serialize, PartialEq)]
|
||||
pub struct Tuning {
|
||||
pub enabled: bool,
|
||||
pub group: HashMap<FirmwareAttribute, i32>,
|
||||
pub group: HashMap<FirmwareAttribute, i32>
|
||||
}
|
||||
type Tunings = HashMap<PlatformProfile, Tuning>;
|
||||
|
||||
@@ -25,8 +19,8 @@ type Tunings = HashMap<PlatformProfile, Tuning>;
|
||||
pub struct Config {
|
||||
// The current charge limit applied
|
||||
pub charge_control_end_threshold: u8,
|
||||
/// Save charge limit for restoring after one-shot full charge
|
||||
#[serde(default = "default_base_charge_limit")]
|
||||
/// Save charge limit for restoring
|
||||
#[serde(skip)]
|
||||
pub base_charge_control_end_threshold: u8,
|
||||
pub disable_nvidia_powerd_on_battery: bool,
|
||||
/// An optional command/script to run when power is changed to AC
|
||||
@@ -49,19 +43,13 @@ pub struct Config {
|
||||
/// The energy_performance_preference for this platform profile
|
||||
pub profile_balanced_epp: CPUEPP,
|
||||
/// 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 ac_profile_tunings: Tunings,
|
||||
pub dc_profile_tunings: Tunings,
|
||||
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
|
||||
#[serde(skip)]
|
||||
pub last_power_plugged: u8,
|
||||
pub last_power_plugged: u8
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -73,28 +61,12 @@ impl Config {
|
||||
};
|
||||
config.entry(profile).or_insert_with(Tuning::default)
|
||||
}
|
||||
|
||||
pub fn select_tunings_ref(
|
||||
&self,
|
||||
power_plugged: bool,
|
||||
profile: PlatformProfile,
|
||||
) -> Option<&Tuning> {
|
||||
let config = if power_plugged {
|
||||
&self.ac_profile_tunings
|
||||
} else {
|
||||
&self.dc_profile_tunings
|
||||
};
|
||||
config.get(&profile)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
charge_control_end_threshold: 100,
|
||||
// NOTE: This is intentionally 100 (not 0 like the serde default).
|
||||
// New installs get 100 (no limit). Upgraded configs missing this
|
||||
// field get 0 via serde, which skips restore_charge_limit().
|
||||
base_charge_control_end_threshold: 100,
|
||||
disable_nvidia_powerd_on_battery: true,
|
||||
ac_command: Default::default(),
|
||||
@@ -107,13 +79,10 @@ impl Default for Config {
|
||||
profile_quiet_epp: CPUEPP::Power,
|
||||
profile_balanced_epp: CPUEPP::BalancePower,
|
||||
profile_performance_epp: CPUEPP::Performance,
|
||||
profile_custom_epp: CPUEPP::Performance,
|
||||
ac_profile_tunings: HashMap::default(),
|
||||
dc_profile_tunings: HashMap::default(),
|
||||
armoury_settings: HashMap::default(),
|
||||
last_power_plugged: Default::default(),
|
||||
screenpad_gamma: Default::default(),
|
||||
screenpad_sync_primary: Default::default(),
|
||||
last_power_plugged: Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,64 +109,7 @@ impl StdConfig 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
|
||||
}
|
||||
}
|
||||
impl StdConfigLoad1<Config601> for Config {}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Config601 {
|
||||
@@ -235,7 +147,7 @@ pub struct Config601 {
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
pub nv_temp_target: Option<u8>,
|
||||
#[serde(skip)]
|
||||
pub last_power_plugged: u8,
|
||||
pub last_power_plugged: u8
|
||||
}
|
||||
|
||||
impl From<Config601> for Config {
|
||||
@@ -255,13 +167,10 @@ impl From<Config601> for Config {
|
||||
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(),
|
||||
armoury_settings: HashMap::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,348 +0,0 @@
|
||||
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(())
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ use std::sync::Arc;
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use futures_lite::StreamExt;
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
||||
use rog_profiles::error::ProfileError;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use zbus::object_server::SignalEmitter;
|
||||
use zbus::{interface, Connection};
|
||||
|
||||
@@ -23,7 +23,7 @@ pub const FAN_CURVE_ZBUS_PATH: &str = "/xyz/ljones";
|
||||
pub struct FanCurveConfig {
|
||||
pub profiles: FanCurveProfiles,
|
||||
#[serde(skip)]
|
||||
pub current: PlatformProfile,
|
||||
pub current: PlatformProfile
|
||||
}
|
||||
|
||||
impl StdConfig for FanCurveConfig {
|
||||
@@ -47,7 +47,7 @@ impl StdConfigLoad for FanCurveConfig {}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CtrlFanCurveZbus {
|
||||
config: Arc<Mutex<FanCurveConfig>>,
|
||||
platform: RogPlatform,
|
||||
platform: RogPlatform
|
||||
}
|
||||
|
||||
// Non-zbus-derive impl
|
||||
@@ -66,8 +66,11 @@ impl CtrlFanCurveZbus {
|
||||
info!("Fetching default fan curves");
|
||||
|
||||
let current = platform.get_platform_profile()?;
|
||||
let profiles = platform.get_platform_profile_choices()?;
|
||||
for this in profiles {
|
||||
for this in [
|
||||
PlatformProfile::Balanced,
|
||||
PlatformProfile::Performance,
|
||||
PlatformProfile::Quiet
|
||||
] {
|
||||
// For each profile we need to switch to it before we
|
||||
// can read the existing values from hardware. The ACPI method used
|
||||
// for this is what limits us.
|
||||
@@ -90,7 +93,7 @@ impl CtrlFanCurveZbus {
|
||||
|
||||
return Ok(Self {
|
||||
config: Arc::new(Mutex::new(config)),
|
||||
platform,
|
||||
platform
|
||||
});
|
||||
}
|
||||
|
||||
@@ -105,7 +108,7 @@ impl CtrlFanCurveZbus {
|
||||
async fn set_fan_curves_enabled(
|
||||
&mut self,
|
||||
profile: PlatformProfile,
|
||||
enabled: bool,
|
||||
enabled: bool
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.config
|
||||
.lock()
|
||||
@@ -127,7 +130,7 @@ impl CtrlFanCurveZbus {
|
||||
&mut self,
|
||||
profile: PlatformProfile,
|
||||
fan: FanCurvePU,
|
||||
enabled: bool,
|
||||
enabled: bool
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.config
|
||||
.lock()
|
||||
@@ -146,7 +149,7 @@ impl CtrlFanCurveZbus {
|
||||
/// Get the fan-curve data for the currently active ThrottlePolicy
|
||||
async fn fan_curve_data(
|
||||
&mut self,
|
||||
profile: PlatformProfile,
|
||||
profile: PlatformProfile
|
||||
) -> zbus::fdo::Result<Vec<CurveData>> {
|
||||
let curve = self
|
||||
.config
|
||||
@@ -163,7 +166,7 @@ impl CtrlFanCurveZbus {
|
||||
async fn set_fan_curve(
|
||||
&mut self,
|
||||
profile: PlatformProfile,
|
||||
curve: CurveData,
|
||||
curve: CurveData
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.config
|
||||
.lock()
|
||||
@@ -213,7 +216,7 @@ impl CtrlFanCurveZbus {
|
||||
.lock()
|
||||
.await
|
||||
.profiles
|
||||
.set_active_curve_to_defaults(active.as_str().into(), &mut find_fan_curve_node()?)?;
|
||||
.set_active_curve_to_defaults((&active).into(), &mut find_fan_curve_node()?)?;
|
||||
self.platform.set_platform_profile(active.as_str())?;
|
||||
|
||||
self.config.lock().await.write();
|
||||
@@ -258,7 +261,7 @@ impl CtrlTask for CtrlFanCurveZbus {
|
||||
.profiles
|
||||
.write_profile_curve_to_platform(
|
||||
profile,
|
||||
&mut find_fan_curve_node().unwrap(),
|
||||
&mut find_fan_curve_node().unwrap()
|
||||
)
|
||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
||||
.ok();
|
||||
|
||||
@@ -3,17 +3,17 @@ use std::process::Command;
|
||||
use std::sync::Arc;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
||||
use rog_platform::power::AsusPower;
|
||||
use tokio::sync::Mutex;
|
||||
use zbus::fdo::Error as FdoErr;
|
||||
use zbus::object_server::SignalEmitter;
|
||||
use zbus::{interface, Connection};
|
||||
|
||||
use crate::asus_armoury::{set_config_or_default, ArmouryAttributeRegistry};
|
||||
use crate::asus_armoury::set_config_or_default;
|
||||
use crate::config::Config;
|
||||
use crate::error::RogError;
|
||||
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
|
||||
@@ -45,22 +45,17 @@ pub struct CtrlPlatform {
|
||||
platform: RogPlatform,
|
||||
attributes: FirmwareAttributes,
|
||||
cpu_control: Option<CPUControl>,
|
||||
config: Arc<Mutex<Config>>,
|
||||
connection: Connection,
|
||||
armoury_registry: ArmouryAttributeRegistry,
|
||||
config: Arc<Mutex<Config>>
|
||||
}
|
||||
|
||||
impl CtrlPlatform {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
attributes: FirmwareAttributes,
|
||||
config: Arc<Mutex<Config>>,
|
||||
config_path: &Path,
|
||||
signal_context: SignalEmitter<'static>,
|
||||
connection: Connection,
|
||||
armoury_registry: ArmouryAttributeRegistry,
|
||||
signal_context: SignalEmitter<'static>
|
||||
) -> Result<Self, RogError> {
|
||||
let config1 = config.clone();
|
||||
let config_path = config_path.to_owned();
|
||||
@@ -72,9 +67,7 @@ impl CtrlPlatform {
|
||||
config,
|
||||
cpu_control: CPUControl::new()
|
||||
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
||||
.ok(),
|
||||
connection,
|
||||
armoury_registry,
|
||||
.ok()
|
||||
};
|
||||
let mut inotify_self = ret_self.clone();
|
||||
|
||||
@@ -93,7 +86,7 @@ impl CtrlPlatform {
|
||||
inotify::WatchMask::MODIFY
|
||||
| inotify::WatchMask::CLOSE_WRITE
|
||||
| inotify::WatchMask::ATTRIB
|
||||
| inotify::WatchMask::CREATE,
|
||||
| inotify::WatchMask::CREATE
|
||||
)
|
||||
.inspect_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
@@ -135,7 +128,7 @@ impl CtrlPlatform {
|
||||
if limit > 0
|
||||
&& std::mem::replace(
|
||||
&mut self.config.lock().await.charge_control_end_threshold,
|
||||
limit,
|
||||
limit
|
||||
) != limit
|
||||
{
|
||||
self.power
|
||||
@@ -168,7 +161,7 @@ impl CtrlPlatform {
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
};
|
||||
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||
if prog.len() > 1 {
|
||||
let mut cmd = Command::new(&prog[0]);
|
||||
for arg in prog.iter().skip(1) {
|
||||
cmd.arg(arg);
|
||||
@@ -217,9 +210,7 @@ impl CtrlPlatform {
|
||||
match throttle {
|
||||
PlatformProfile::Balanced => self.config.lock().await.profile_balanced_epp,
|
||||
PlatformProfile::Performance => self.config.lock().await.profile_performance_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,
|
||||
PlatformProfile::Quiet => self.config.lock().await.profile_quiet_epp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,39 +286,16 @@ impl CtrlPlatform {
|
||||
|
||||
#[zbus(property)]
|
||||
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
||||
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:?}"
|
||||
))
|
||||
})?;
|
||||
|
||||
let limit = self.power.get_charge_control_end_threshold()?;
|
||||
Ok(limit)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
||||
if !self.power.has_charge_control_end_threshold() {
|
||||
return Err(FdoErr::NotSupported(
|
||||
"RogPlatform: charge_control_end_threshold not supported".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
if !(20..=100).contains(&limit) {
|
||||
return Err(RogError::ChargeLimit(limit))?;
|
||||
}
|
||||
|
||||
self.power
|
||||
.set_charge_control_end_threshold(limit)
|
||||
.map_err(|e| {
|
||||
FdoErr::Failed(format!("Could not set charge_control_end_threshold: {e:?}"))
|
||||
})?;
|
||||
|
||||
self.power.set_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.write();
|
||||
@@ -335,22 +303,12 @@ impl CtrlPlatform {
|
||||
}
|
||||
|
||||
async fn one_shot_full_charge(&self) -> Result<(), FdoErr> {
|
||||
if !self.power.has_charge_control_end_threshold() {
|
||||
return Err(FdoErr::NotSupported(
|
||||
"RogPlatform: charge_control_end_threshold not supported".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
let base_limit = std::mem::replace(
|
||||
&mut self.config.lock().await.charge_control_end_threshold,
|
||||
100,
|
||||
100
|
||||
);
|
||||
if base_limit != 100 {
|
||||
self.power
|
||||
.set_charge_control_end_threshold(100)
|
||||
.map_err(|e| {
|
||||
FdoErr::Failed(format!("Could not set one_shot_full_charge: {e:?}"))
|
||||
})?;
|
||||
self.power.set_charge_control_end_threshold(100)?;
|
||||
self.config.lock().await.base_charge_control_end_threshold = base_limit;
|
||||
self.config.lock().await.write();
|
||||
}
|
||||
@@ -361,13 +319,11 @@ impl CtrlPlatform {
|
||||
/// If fan-curves are supported will also activate a fan curve for profile.
|
||||
async fn next_platform_profile(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>
|
||||
) -> Result<(), FdoErr> {
|
||||
let policy: PlatformProfile =
|
||||
platform_get_value!(self, platform_profile, "platform_profile").map(|n| n.into())?;
|
||||
let choices =
|
||||
platform_get_value!(self, platform_profile_choices, "platform_profile_choices")?;
|
||||
let policy = PlatformProfile::next(policy, &choices);
|
||||
let policy = PlatformProfile::next(policy);
|
||||
|
||||
if self.platform.has_platform_profile() {
|
||||
let change_epp = self.config.lock().await.platform_profile_linked_epp;
|
||||
@@ -383,27 +339,21 @@ impl CtrlPlatform {
|
||||
Ok(self.platform_profile_changed(&ctxt).await?)
|
||||
} else {
|
||||
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)]
|
||||
fn platform_profile(&self) -> Result<PlatformProfile, FdoErr> {
|
||||
let policy: PlatformProfile = self.platform.get_platform_profile()?.as_str().into();
|
||||
Ok(policy)
|
||||
platform_get_value!(self, platform_profile, "platform_profile").map(|n| n.into())
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_platform_profile(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
policy: PlatformProfile,
|
||||
policy: PlatformProfile
|
||||
) -> Result<(), FdoErr> {
|
||||
// TODO: watch for external changes
|
||||
if self.platform.has_platform_profile() {
|
||||
@@ -412,15 +362,7 @@ impl CtrlPlatform {
|
||||
self.check_and_set_epp(epp, change_epp);
|
||||
|
||||
self.config.lock().await.write();
|
||||
|
||||
let choices = self.platform.get_platform_profile_choices()?;
|
||||
if !choices.contains(&policy) {
|
||||
return Err(FdoErr::NotSupported(format!(
|
||||
"RogPlatform: platform_profile: {} not supported",
|
||||
policy
|
||||
)));
|
||||
}
|
||||
|
||||
// TODO: Need to get supported profiles here and ensure we translate to one
|
||||
self.platform
|
||||
.set_platform_profile(policy.into())
|
||||
.map_err(|err| {
|
||||
@@ -431,7 +373,7 @@ impl CtrlPlatform {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(FdoErr::NotSupported(
|
||||
"RogPlatform: platform_profile not supported".to_owned(),
|
||||
"RogPlatform: platform_profile not supported".to_owned()
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -457,7 +399,7 @@ impl CtrlPlatform {
|
||||
async fn set_platform_profile_on_battery(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
policy: PlatformProfile,
|
||||
policy: PlatformProfile
|
||||
) -> Result<(), FdoErr> {
|
||||
self.config.lock().await.platform_profile_on_battery = policy;
|
||||
self.set_platform_profile(ctxt, policy).await?;
|
||||
@@ -486,7 +428,7 @@ impl CtrlPlatform {
|
||||
async fn set_platform_profile_on_ac(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
policy: PlatformProfile,
|
||||
policy: PlatformProfile
|
||||
) -> Result<(), FdoErr> {
|
||||
self.config.lock().await.platform_profile_on_ac = policy;
|
||||
self.set_platform_profile(ctxt, policy).await?;
|
||||
@@ -651,7 +593,7 @@ impl ReloadAndNotify for CtrlPlatform {
|
||||
async fn reload_and_notify(
|
||||
&mut self,
|
||||
signal_context: &SignalEmitter<'static>,
|
||||
data: Self::Data,
|
||||
data: Self::Data
|
||||
) -> Result<(), RogError> {
|
||||
let mut config = self.config.lock().await;
|
||||
if *config != data {
|
||||
@@ -680,9 +622,7 @@ impl ReloadAndNotify for CtrlPlatform {
|
||||
let epp = match profile {
|
||||
PlatformProfile::Balanced => data.profile_balanced_epp,
|
||||
PlatformProfile::Performance => data.profile_performance_epp,
|
||||
PlatformProfile::Quiet => data.profile_quiet_epp,
|
||||
PlatformProfile::LowPower => data.profile_quiet_epp,
|
||||
PlatformProfile::Custom => data.profile_custom_epp,
|
||||
PlatformProfile::Quiet => data.profile_quiet_epp
|
||||
};
|
||||
warn!("setting epp to {epp:?}");
|
||||
self.check_and_set_epp(epp, true);
|
||||
@@ -754,7 +694,7 @@ impl CtrlTask for CtrlPlatform {
|
||||
platform1
|
||||
.power
|
||||
.set_charge_control_end_threshold(
|
||||
platform1.config.lock().await.charge_control_end_threshold,
|
||||
platform1.config.lock().await.charge_control_end_threshold
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
@@ -769,31 +709,6 @@ impl CtrlTask for CtrlPlatform {
|
||||
}
|
||||
if !sleeping {
|
||||
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||
if let Ok(profile) =
|
||||
platform1.platform.get_platform_profile().map(|p| p.into())
|
||||
{
|
||||
let attrs = FirmwareAttributes::new();
|
||||
{
|
||||
let mut cfg = platform1.config.lock().await;
|
||||
set_config_or_default(
|
||||
&attrs,
|
||||
&mut cfg,
|
||||
power_plugged > 0,
|
||||
profile,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
if let Err(e) = platform1
|
||||
.armoury_registry
|
||||
.emit_limits(&platform1.connection)
|
||||
.await
|
||||
{
|
||||
error!(
|
||||
"Failed to emit armoury updates after power change: \
|
||||
{e:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
platform1.config.lock().await.last_power_plugged = power_plugged;
|
||||
}
|
||||
@@ -813,7 +728,7 @@ impl CtrlTask for CtrlPlatform {
|
||||
platform2
|
||||
.power
|
||||
.set_charge_control_end_threshold(
|
||||
lock.base_charge_control_end_threshold,
|
||||
lock.base_charge_control_end_threshold
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlCharge: charge_control_end_threshold {}", err);
|
||||
@@ -854,24 +769,20 @@ impl CtrlTask for CtrlPlatform {
|
||||
{
|
||||
// TODO: manage this better, shouldn't need to create every time
|
||||
let attrs = FirmwareAttributes::new();
|
||||
{
|
||||
let mut cfg = platform3.config.lock().await;
|
||||
set_config_or_default(&attrs, &mut cfg, power_plugged, profile).await;
|
||||
}
|
||||
if let Err(e) = platform3
|
||||
.armoury_registry
|
||||
.emit_limits(&platform3.connection)
|
||||
.await
|
||||
{
|
||||
error!("Failed to emit armoury updates after AC/DC toggle: {e:?}");
|
||||
}
|
||||
set_config_or_default(
|
||||
&attrs,
|
||||
&mut *platform3.config.lock().await,
|
||||
power_plugged,
|
||||
profile
|
||||
)
|
||||
.await;
|
||||
platform3
|
||||
.enable_ppt_group_changed(&signal_ctxt_copy)
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -918,12 +829,9 @@ impl CtrlTask for CtrlPlatform {
|
||||
&attrs,
|
||||
&mut *ctrl.config.lock().await,
|
||||
power_plugged == 1,
|
||||
profile,
|
||||
profile
|
||||
)
|
||||
.await;
|
||||
if let Err(e) = ctrl.armoury_registry.emit_limits(&ctrl.connection).await {
|
||||
error!("Failed to emit armoury updates after profile change: {e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,25 +3,22 @@ use std::error::Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
use ::zbus::Connection;
|
||||
use asusd::asus_armoury::{start_attributes_zbus, ArmouryAttributeRegistry};
|
||||
use asusd::asus_armoury::start_attributes_zbus;
|
||||
use asusd::aura_manager::DeviceManager;
|
||||
use asusd::config::Config;
|
||||
use asusd::ctrl_backlight::CtrlBacklight;
|
||||
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
||||
use asusd::ctrl_platform::CtrlPlatform;
|
||||
use asusd::{print_board_info, start_tasks, CtrlTask, ZbusRun, DBUS_NAME};
|
||||
use config_traits::{StdConfig, StdConfigLoad2};
|
||||
use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME};
|
||||
use config_traits::{StdConfig, StdConfigLoad1};
|
||||
use futures_util::lock::Mutex;
|
||||
use log::{error, info};
|
||||
use rog_platform::asus_armoury::FirmwareAttributes;
|
||||
use rog_platform::platform::RogPlatform;
|
||||
use rog_platform::power::AsusPower;
|
||||
use tokio::sync::Mutex;
|
||||
use zbus::fdo::ObjectManager;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Starting asusd daemon...");
|
||||
|
||||
// console_subscriber::init();
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
@@ -33,7 +30,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let is_service = match env::var_os("IS_SERVICE") {
|
||||
Some(val) => val == "1",
|
||||
None => true,
|
||||
None => true
|
||||
};
|
||||
|
||||
if !is_service {
|
||||
@@ -64,9 +61,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// Start zbus server
|
||||
let mut server = Connection::system().await?;
|
||||
if let Err(e) = server.object_server().at("/", ObjectManager).await {
|
||||
error!("Failed to register ObjectManager at root '/': {e:?}");
|
||||
}
|
||||
server.object_server().at("/", ObjectManager).await.unwrap();
|
||||
|
||||
let config = Config::new().load();
|
||||
let cfg_path = config.file_path();
|
||||
@@ -76,64 +71,36 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
|
||||
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
|
||||
let attributes = FirmwareAttributes::new();
|
||||
let armoury_registry = match start_attributes_zbus(
|
||||
start_attributes_zbus(
|
||||
&server,
|
||||
platform.clone(),
|
||||
power.clone(),
|
||||
attributes.clone(),
|
||||
config.clone(),
|
||||
config.clone()
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(registry) => {
|
||||
info!("attribute on zbus initialized");
|
||||
registry
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to initialize firmware attributes over zbus: {e:?}");
|
||||
ArmouryAttributeRegistry::default()
|
||||
}
|
||||
};
|
||||
.await?;
|
||||
|
||||
match CtrlFanCurveZbus::new() {
|
||||
Ok(ctrl) => {
|
||||
info!("FanCurves: found supported fancurves");
|
||||
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
|
||||
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
||||
info!("FanCurves: initialized");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("FanCurves: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
platform,
|
||||
power,
|
||||
attributes,
|
||||
config.clone(),
|
||||
&cfg_path,
|
||||
CtrlPlatform::signal_context(&server)?,
|
||||
server.clone(),
|
||||
armoury_registry,
|
||||
CtrlPlatform::signal_context(&server)?
|
||||
) {
|
||||
Ok(ctrl) => {
|
||||
info!("CtrlPlatform: initialized");
|
||||
let sig_ctx = CtrlPlatform::signal_context(&server)?;
|
||||
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
||||
info!("CtrlPlatform: tasks started");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("CtrlPlatform: {}", err);
|
||||
@@ -142,12 +109,10 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
let _ = DeviceManager::new(server.clone()).await?;
|
||||
|
||||
info!("DeviceManager initialized");
|
||||
|
||||
// Request dbus name after finishing initalizing all functions
|
||||
server.request_name(DBUS_NAME).await?;
|
||||
|
||||
info!("Startup success on dbus name {DBUS_NAME}: begining dbus server loop");
|
||||
info!("Startup success, begining dbus server loop");
|
||||
loop {
|
||||
// This is just a blocker to idle and ensure the reator reacts
|
||||
server.executor().tick().await;
|
||||
|
||||
@@ -37,7 +37,7 @@ pub enum RogError {
|
||||
SystemdUnitAction(String),
|
||||
SystemdUnitWaitTimeout(String),
|
||||
Command(String, std::io::Error),
|
||||
ParseRon(ron::Error),
|
||||
ParseRon(ron::Error)
|
||||
}
|
||||
|
||||
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::ParseRon(error) => write!(f, "Parse config error: {}", error),
|
||||
RogError::ParseRon(error) => write!(f, "Parse config error: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#![deny(unused_must_use)]
|
||||
/// Configuration loading, saving
|
||||
pub mod config;
|
||||
pub mod ctrl_backlight;
|
||||
/// Control platform profiles + fan-curves if available
|
||||
pub mod ctrl_fancurves;
|
||||
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
||||
@@ -108,7 +107,7 @@ macro_rules! task_watch_item_notify {
|
||||
&self,
|
||||
signal_ctxt: SignalEmitter<'static>,
|
||||
) -> Result<(), RogError> {
|
||||
use futures_util::StreamExt;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
|
||||
let ctrl = self.clone();
|
||||
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||
@@ -150,7 +149,7 @@ pub trait ReloadAndNotify {
|
||||
fn reload_and_notify(
|
||||
&mut self,
|
||||
signal_context: &SignalEmitter<'static>,
|
||||
data: Self::Data,
|
||||
data: Self::Data
|
||||
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||
}
|
||||
|
||||
@@ -160,7 +159,7 @@ pub trait ZbusRun {
|
||||
fn add_to_server_helper(
|
||||
iface: impl Interface,
|
||||
path: &str,
|
||||
server: &mut Connection,
|
||||
server: &mut Connection
|
||||
) -> impl Future<Output = ()> + Send {
|
||||
async move {
|
||||
server
|
||||
@@ -189,7 +188,7 @@ pub trait CtrlTask {
|
||||
/// separate thread.
|
||||
fn create_tasks(
|
||||
&self,
|
||||
signal: SignalEmitter<'static>,
|
||||
signal: SignalEmitter<'static>
|
||||
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||
|
||||
// /// Create a timed repeating task
|
||||
@@ -213,7 +212,7 @@ pub trait CtrlTask {
|
||||
mut on_prepare_for_sleep: F1,
|
||||
mut on_prepare_for_shutdown: F2,
|
||||
mut on_lid_change: F3,
|
||||
mut on_external_power_change: F4,
|
||||
mut on_external_power_change: F4
|
||||
) -> impl Future<Output = ()> + Send
|
||||
where
|
||||
F1: FnMut(bool) -> Fut1 + Send + 'static,
|
||||
@@ -223,7 +222,7 @@ pub trait CtrlTask {
|
||||
Fut1: Future<Output = ()> + Send,
|
||||
Fut2: Future<Output = ()> + Send,
|
||||
Fut3: Future<Output = ()> + Send,
|
||||
Fut4: Future<Output = ()> + Send,
|
||||
Fut4: Future<Output = ()> + Send
|
||||
{
|
||||
async {
|
||||
let connection = Connection::system()
|
||||
@@ -303,10 +302,10 @@ pub trait GetSupported {
|
||||
pub async fn start_tasks<T>(
|
||||
mut zbus: T,
|
||||
connection: &mut Connection,
|
||||
signal_ctx: SignalEmitter<'static>,
|
||||
signal_ctx: SignalEmitter<'static>
|
||||
) -> Result<(), RogError>
|
||||
where
|
||||
T: ZbusRun + Reloadable + CtrlTask + Clone,
|
||||
T: ZbusRun + Reloadable + CtrlTask + Clone
|
||||
{
|
||||
let zbus_clone = zbus.clone();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use serde::Serialize;
|
||||
/// implemented, the rest are intended to be free methods.
|
||||
pub trait StdConfig
|
||||
where
|
||||
Self: Serialize + DeserializeOwned,
|
||||
Self: Serialize + DeserializeOwned
|
||||
{
|
||||
/// Taking over the standard `new()` to ensure things can be generic
|
||||
fn new() -> Self;
|
||||
|
||||
@@ -9,14 +9,11 @@ ENV{DMI_FAMILY}=="*Strix*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*Zenbook*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*ProArt*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*TX Air*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*TX Gaming*", GOTO="asusd_start"
|
||||
ENV{DMI_FAMILY}=="*EXPERTBOOK*", GOTO="asusd_start"
|
||||
# No match so
|
||||
GOTO="asusd_end"
|
||||
|
||||
LABEL="asusd_start"
|
||||
ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
|
||||
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", 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"
|
||||
|
||||
LABEL="asusd_end"
|
||||
|
||||
@@ -6,10 +6,7 @@ After=nvidia-powerd.service systemd-udevd.service
|
||||
|
||||
[Service]
|
||||
Environment=IS_SERVICE=1
|
||||
# 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"
|
||||
Environment=RUST_LOG="debug"
|
||||
# required to prevent init issues with hid_asus and MCU
|
||||
ExecStartPre=/bin/sleep 1
|
||||
ExecStart=/usr/bin/asusd
|
||||
|
||||
130
distro-packaging/asusctl.spec
Normal file → Executable file
130
distro-packaging/asusctl.spec
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package asus-nb-ctrl
|
||||
#
|
||||
# Copyright (c) 2020-2025 Luke Jones <luke@ljones.dev>
|
||||
# Copyright (c) 2020-2021 Luke Jones <luke@ljones.dev>
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@@ -20,44 +20,42 @@
|
||||
%global debug_package %{nil}
|
||||
%endif
|
||||
|
||||
%define version 6.2.0
|
||||
%define specrelease %{?dist}
|
||||
%define pkg_release 1%{specrelease}
|
||||
%define pkg_release 3%{specrelease}
|
||||
|
||||
# Use hardening ldflags.
|
||||
%global rustflags -Clink-arg=-Wl,-z,relro,-z,now
|
||||
Name: asusctl
|
||||
Version: %{version}
|
||||
Name: asusctl
|
||||
Version: 6.0.7
|
||||
Release: %{pkg_release}
|
||||
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
|
||||
License: MPLv2
|
||||
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
|
||||
License: MPLv2
|
||||
|
||||
Group: System Environment/Kernel
|
||||
Group: System Environment/Kernel
|
||||
|
||||
URL: https://gitlab.com/asus-linux/asusctl
|
||||
Source: https://gitlab.com/asus-linux/asusctl/-/archive/%{version}/%{name}-%{version}.tar.gz
|
||||
URL: https://gitlab.com/asus-linux/asusctl
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Source1: vendor_%{name}_%{version}.tar.xz
|
||||
Source2: cargo-config
|
||||
|
||||
%if %{defined fedora}
|
||||
BuildRequires: cargo
|
||||
BuildRequires: rust-packaging
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%else
|
||||
BuildRequires: cargo-packaging
|
||||
%endif
|
||||
BuildRequires: git
|
||||
BuildRequires: clang-devel
|
||||
BuildRequires: cargo
|
||||
BuildRequires: cmake
|
||||
BuildRequires: rust
|
||||
BuildRequires: rust-std-static
|
||||
BuildRequires: pkgconfig(gbm)
|
||||
BuildRequires: pkgconfig(libinput)
|
||||
BuildRequires: pkgconfig(libseat)
|
||||
BuildRequires: pkgconfig(expat)
|
||||
BuildRequires: pkgconfig(dbus-1)
|
||||
BuildRequires: pkgconfig(libudev)
|
||||
BuildRequires: pkgconfig(xkbcommon)
|
||||
BuildRequires: pkgconfig(libzstd)
|
||||
BuildRequires: pkgconfig(fontconfig)
|
||||
BuildRequires: pkgconfig(gtk+-3.0)
|
||||
BuildRequires: pkgconfig(gdk-3.0)
|
||||
BuildRequires: desktop-file-utils
|
||||
|
||||
# expat-devel pcre2-devel
|
||||
|
||||
%description
|
||||
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.
|
||||
@@ -68,93 +66,38 @@ asus-nb-ctrl enables third-party apps to use the above with dbus methods.
|
||||
|
||||
%package rog-gui
|
||||
Summary: An experimental GUI for %{name}
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description rog-gui
|
||||
A one-stop-shop GUI tool for asusd/asusctl. It aims to provide most controls,
|
||||
a notification service, and ability to run in the background.
|
||||
|
||||
%prep
|
||||
# %setup -D -T -a 1 -c -n %{name}-%{version}/vendor
|
||||
# %setup -D -T -a 0 -c
|
||||
%autosetup
|
||||
mkdir -p .cargo
|
||||
cat > .cargo/config.toml << 'EOF'
|
||||
[term]
|
||||
verbose = true
|
||||
[net]
|
||||
offline = false
|
||||
EOF
|
||||
%setup -D -T -a 1
|
||||
|
||||
mv Cargo.lock{,.bak}
|
||||
%cargo_prep
|
||||
mv Cargo.lock{.bak,}
|
||||
sed -i 's|replace-with = "local-registry"|replace-with = "vendored-sources"|' .cargo/config
|
||||
cat %{SOURCE2} >> .cargo/config
|
||||
|
||||
%build
|
||||
export RUSTFLAGS="%{rustflags}"
|
||||
%if %{defined fedora}
|
||||
/usr/bin/cargo build --release --locked
|
||||
%else
|
||||
/usr/bin/cargo auditable build --release --locked
|
||||
%endif
|
||||
%cargo_build
|
||||
#cargo build --release --frozen --offline --config .cargo/config.toml
|
||||
|
||||
%install
|
||||
export RUSTFLAGS="%{rustflags}"
|
||||
mkdir -p "%{buildroot}/%{_bindir}" "%{buildroot}%{_docdir}"
|
||||
%make_install
|
||||
|
||||
%define _target_dir target/release
|
||||
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 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
|
||||
desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.desktop
|
||||
|
||||
%files
|
||||
%license LICENSE
|
||||
@@ -164,6 +107,8 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/rog-control-center.de
|
||||
%{_unitdir}/asusd.service
|
||||
%{_userunitdir}/asusd-user.service
|
||||
%{_udevrulesdir}/99-asusd.rules
|
||||
#%dir %{_sysconfdir}/asusd/
|
||||
%{_datadir}/asusd/aura_support.ron
|
||||
%{_datadir}/dbus-1/system.d/asusd.conf
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
|
||||
@@ -178,7 +123,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/rog-control-center.de
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-vfio.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
|
||||
%{_docdir}/%{name}/
|
||||
%{_datadir}/asusctl/
|
||||
%{_datadir}/asusd/
|
||||
|
||||
%files rog-gui
|
||||
|
||||
@@ -12,7 +12,7 @@ pub struct DMIID {
|
||||
pub bios_vendor: String,
|
||||
pub bios_version: String,
|
||||
pub product_family: String,
|
||||
pub product_name: String,
|
||||
pub product_name: String
|
||||
}
|
||||
|
||||
impl DMIID {
|
||||
@@ -77,7 +77,7 @@ impl DMIID {
|
||||
product_name: device
|
||||
.attribute_value("product_name")
|
||||
.map(|s| s.to_string_lossy().to_string())
|
||||
.unwrap_or("Unknown".to_string()),
|
||||
.unwrap_or("Unknown".to_string())
|
||||
});
|
||||
}
|
||||
Err("dmi not found".into())
|
||||
|
||||
@@ -23,15 +23,15 @@ const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
||||
|
||||
/// First packet is for GA401 + GA402
|
||||
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
|
||||
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
|
||||
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))]
|
||||
@@ -40,7 +40,7 @@ pub struct Animations {
|
||||
pub boot: AnimBooting,
|
||||
pub awake: AnimAwake,
|
||||
pub sleep: AnimSleeping,
|
||||
pub shutdown: AnimShutdown,
|
||||
pub shutdown: AnimShutdown
|
||||
}
|
||||
|
||||
// TODO: move this out
|
||||
@@ -54,7 +54,7 @@ pub struct DeviceState {
|
||||
pub off_when_unplugged: bool,
|
||||
pub off_when_suspended: 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"))]
|
||||
@@ -63,31 +63,20 @@ pub enum AnimeType {
|
||||
GA401,
|
||||
GA402,
|
||||
GU604,
|
||||
G635L,
|
||||
G835L,
|
||||
#[default]
|
||||
Unsupported,
|
||||
Unsupported
|
||||
}
|
||||
|
||||
impl FromStr for AnimeType {
|
||||
type Err = AnimeError;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let dmi = s.to_uppercase();
|
||||
|
||||
if dmi.contains("GA401") {
|
||||
return Ok(Self::GA401);
|
||||
} else if dmi.contains("GA402") {
|
||||
return Ok(Self::GA402);
|
||||
} else if dmi.contains("GU604") {
|
||||
return Ok(Self::GU604);
|
||||
} else if dmi.contains("G635L") {
|
||||
return Ok(Self::G635L);
|
||||
} else if dmi.contains("G835L") {
|
||||
return Ok(Self::G835L);
|
||||
}
|
||||
|
||||
Ok(Self::Unsupported)
|
||||
Ok(match s {
|
||||
"ga401" | "GA401" => Self::GA401,
|
||||
"ga402" | "GA402" => Self::GA402,
|
||||
"gu604" | "GU604" => Self::GU604,
|
||||
_ => Self::Unsupported
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +89,6 @@ impl AnimeType {
|
||||
AnimeType::GA402
|
||||
} else if board_name.contains("GU604V") {
|
||||
AnimeType::GU604
|
||||
} else if board_name.contains("G635L") || board_name.contains("G635L") {
|
||||
AnimeType::G635L
|
||||
} else {
|
||||
AnimeType::Unsupported
|
||||
}
|
||||
@@ -111,8 +98,7 @@ impl AnimeType {
|
||||
pub fn width(&self) -> usize {
|
||||
match self {
|
||||
AnimeType::GU604 => 70,
|
||||
AnimeType::G835L => 74,
|
||||
_ => 74,
|
||||
_ => 74
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +107,7 @@ impl AnimeType {
|
||||
match self {
|
||||
AnimeType::GA401 => 36,
|
||||
AnimeType::GU604 => 43,
|
||||
AnimeType::G835L => 39,
|
||||
_ => 39,
|
||||
_ => 39
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +116,7 @@ impl AnimeType {
|
||||
match self {
|
||||
AnimeType::GA401 => PANE_LEN * 2,
|
||||
AnimeType::GU604 => PANE_LEN * 3,
|
||||
AnimeType::G835L => PANE_LEN * 3,
|
||||
_ => PANE_LEN * 3,
|
||||
_ => PANE_LEN * 3
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +127,7 @@ impl AnimeType {
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct AnimeDataBuffer {
|
||||
data: Vec<u8>,
|
||||
anime: AnimeType,
|
||||
anime: AnimeType
|
||||
}
|
||||
|
||||
impl AnimeDataBuffer {
|
||||
@@ -153,7 +137,7 @@ impl AnimeDataBuffer {
|
||||
|
||||
AnimeDataBuffer {
|
||||
data: vec![0u8; len],
|
||||
anime,
|
||||
anime
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,13 +180,7 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
|
||||
|
||||
let mut buffers = match anime.anime {
|
||||
AnimeType::GA401 => vec![[0; 640]; 2],
|
||||
AnimeType::GA402
|
||||
| AnimeType::GU604
|
||||
| AnimeType::G635L
|
||||
| AnimeType::G835L
|
||||
| AnimeType::Unsupported => {
|
||||
vec![[0; 640]; 3]
|
||||
}
|
||||
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported => vec![[0; 640]; 3]
|
||||
};
|
||||
|
||||
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
|
||||
@@ -213,11 +191,7 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
|
||||
|
||||
if matches!(
|
||||
anime.anime,
|
||||
AnimeType::GA402
|
||||
| AnimeType::GU604
|
||||
| AnimeType::G635L
|
||||
| AnimeType::G835L
|
||||
| AnimeType::Unsupported
|
||||
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported
|
||||
) {
|
||||
buffers[2][..7].copy_from_slice(&USB_PREFIX3);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ impl AnimeDiagonal {
|
||||
Self(
|
||||
anime_type,
|
||||
vec![vec![0; anime_type.width()]; anime_type.height()],
|
||||
duration,
|
||||
duration
|
||||
)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ impl AnimeDiagonal {
|
||||
path: &Path,
|
||||
duration: Option<Duration>,
|
||||
bright: f32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
let data = std::fs::read(path).map_err(|e| {
|
||||
error!("Could not open {path:?}: {e:?}");
|
||||
@@ -86,7 +86,7 @@ impl AnimeDiagonal {
|
||||
png_pong::PngRaster::Rgba16(ras) => {
|
||||
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)
|
||||
@@ -96,9 +96,9 @@ impl AnimeDiagonal {
|
||||
ras: &pix::Raster<P>,
|
||||
matrix: &mut AnimeDiagonal,
|
||||
bright: f32,
|
||||
grey: bool,
|
||||
grey: bool
|
||||
) where
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>,
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>
|
||||
{
|
||||
let width = ras.width();
|
||||
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
||||
@@ -121,9 +121,9 @@ impl AnimeDiagonal {
|
||||
ras: &pix::Raster<P>,
|
||||
matrix: &mut AnimeDiagonal,
|
||||
bright: f32,
|
||||
grey: bool,
|
||||
grey: bool
|
||||
) where
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>,
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>
|
||||
{
|
||||
let width = ras.width();
|
||||
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
||||
@@ -146,7 +146,7 @@ impl AnimeDiagonal {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => self.to_ga401_packets(),
|
||||
AnimeType::GU604 => self.to_gu604_packets(),
|
||||
_ => self.to_ga402_packets(),
|
||||
_ => self.to_ga402_packets()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ impl AnimeDiagonal {
|
||||
x: usize,
|
||||
y: usize,
|
||||
start_index: &mut usize,
|
||||
len: usize,
|
||||
len: usize
|
||||
) {
|
||||
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
||||
*start_index += len;
|
||||
@@ -307,7 +307,7 @@ impl AnimeDiagonal {
|
||||
x: usize,
|
||||
y: usize,
|
||||
start_index: &mut usize,
|
||||
len: usize,
|
||||
len: usize
|
||||
) {
|
||||
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
||||
*start_index += len;
|
||||
|
||||
@@ -24,7 +24,7 @@ pub enum AnimeError {
|
||||
DataBufferLength,
|
||||
PixelGifWidth(usize),
|
||||
PixelGifHeight(usize),
|
||||
ParseError(String),
|
||||
ParseError(String)
|
||||
}
|
||||
|
||||
impl fmt::Display for AnimeError {
|
||||
@@ -61,7 +61,7 @@ impl fmt::Display for AnimeError {
|
||||
AnimeError::PixelGifHeight(n) => write!(
|
||||
f,
|
||||
"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
|
||||
/// `AnimePacketType::from(buffer)`
|
||||
data: AnimeDataBuffer,
|
||||
delay: Duration,
|
||||
delay: Duration
|
||||
}
|
||||
|
||||
impl AnimeFrame {
|
||||
@@ -44,7 +44,7 @@ pub enum AnimTime {
|
||||
/// Run for infinite time
|
||||
Infinite,
|
||||
/// Fade in, play for, fade out
|
||||
Fade(Fade),
|
||||
Fade(Fade)
|
||||
}
|
||||
|
||||
impl Default for AnimTime {
|
||||
@@ -59,7 +59,7 @@ impl Default for AnimTime {
|
||||
pub struct Fade {
|
||||
fade_in: Duration,
|
||||
show_for: Option<Duration>,
|
||||
fade_out: Duration,
|
||||
fade_out: Duration
|
||||
}
|
||||
|
||||
impl Fade {
|
||||
@@ -67,7 +67,7 @@ impl Fade {
|
||||
Self {
|
||||
fade_in,
|
||||
show_for,
|
||||
fade_out,
|
||||
fade_out
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ impl AnimeGif {
|
||||
file_name: &Path,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
let mut matrix = AnimeDiagonal::new(anime_type, None);
|
||||
|
||||
@@ -142,7 +142,7 @@ impl AnimeGif {
|
||||
|
||||
frames.push(AnimeFrame {
|
||||
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))
|
||||
@@ -154,7 +154,7 @@ impl AnimeGif {
|
||||
file_name: &Path,
|
||||
anime_type: AnimeType,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
) -> Result<Self> {
|
||||
let image = AnimeDiagonal::from_png(file_name, None, brightness, anime_type)?;
|
||||
|
||||
@@ -170,7 +170,7 @@ impl AnimeGif {
|
||||
|
||||
let single = AnimeFrame {
|
||||
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];
|
||||
|
||||
@@ -187,7 +187,7 @@ impl AnimeGif {
|
||||
translation: Vec2,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
let mut frames = Vec::new();
|
||||
let mut decoder = gif::DecodeOptions::new();
|
||||
@@ -211,7 +211,7 @@ impl AnimeGif {
|
||||
brightness,
|
||||
pixels,
|
||||
decoder.width() as u32,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
while let Some(frame) = decoder.read_next_frame()? {
|
||||
@@ -226,7 +226,7 @@ impl AnimeGif {
|
||||
brightness,
|
||||
pixels,
|
||||
width as u32,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
}
|
||||
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);
|
||||
image.get_mut()[pos] = Pixel {
|
||||
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 {
|
||||
data: <AnimeDataBuffer>::try_from(&image)?,
|
||||
delay: Duration::from_millis(wait as u64),
|
||||
delay: Duration::from_millis(wait as u64)
|
||||
});
|
||||
}
|
||||
Ok(Self(frames, duration))
|
||||
@@ -265,7 +265,7 @@ impl AnimeGif {
|
||||
translation: Vec2,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
let image =
|
||||
AnimeImage::from_png(file_name, scale, angle, translation, brightness, anime_type)?;
|
||||
@@ -282,7 +282,7 @@ impl AnimeGif {
|
||||
|
||||
let single = AnimeFrame {
|
||||
data: <AnimeDataBuffer>::try_from(&image)?,
|
||||
delay: Duration::from_millis(30),
|
||||
delay: Duration::from_millis(30)
|
||||
};
|
||||
let frames = vec![single; frame_count as usize];
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const HEIGHT: usize = 55;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AnimeGrid {
|
||||
anime_type: AnimeType,
|
||||
data: [[u8; WIDTH]; HEIGHT],
|
||||
data: [[u8; WIDTH]; HEIGHT]
|
||||
}
|
||||
|
||||
impl AnimeGrid {
|
||||
@@ -26,7 +26,7 @@ impl AnimeGrid {
|
||||
pub fn new(anime_type: AnimeType) -> Self {
|
||||
Self {
|
||||
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, 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, 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);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::AnimeType;
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Pixel {
|
||||
pub color: u32,
|
||||
pub alpha: f32,
|
||||
pub alpha: f32
|
||||
}
|
||||
|
||||
impl Default for Pixel {
|
||||
@@ -21,7 +21,7 @@ impl Default for Pixel {
|
||||
fn default() -> Self {
|
||||
Pixel {
|
||||
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
|
||||
/// therefore same ID, so the identifier must be by laptop model in
|
||||
/// `AnimeType`.
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
}
|
||||
|
||||
impl AnimeImage {
|
||||
@@ -88,7 +88,7 @@ impl AnimeImage {
|
||||
bright: f32,
|
||||
pixels: Vec<Pixel>,
|
||||
width: u32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
if !(0.0..=1.0).contains(&bright) {
|
||||
return Err(AnimeError::InvalidBrightness(bright));
|
||||
@@ -102,7 +102,7 @@ impl AnimeImage {
|
||||
led_pos: Self::generate_image_positioning(anime_type),
|
||||
img_pixels: pixels,
|
||||
width,
|
||||
anime_type,
|
||||
anime_type
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl AnimeImage {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => 0.8,
|
||||
AnimeType::GU604 => 0.78,
|
||||
_ => 0.77,
|
||||
_ => 0.77
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl AnimeImage {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => 0.3,
|
||||
AnimeType::GU604 => 0.28,
|
||||
_ => 0.283,
|
||||
_ => 0.283
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ impl AnimeImage {
|
||||
// first 5 rows for GA401 are always at X = 0
|
||||
return 0;
|
||||
}
|
||||
y.div_ceil(2) - 3
|
||||
(y + 1) / 2 - 3
|
||||
}
|
||||
AnimeType::GU604 => {
|
||||
// first 9 rows start at zero
|
||||
@@ -185,7 +185,7 @@ impl AnimeImage {
|
||||
return 0;
|
||||
}
|
||||
// and then their offset grows by one every two rows
|
||||
y.div_ceil(2) - 5
|
||||
(y + 1) / 2 - 5
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ impl AnimeImage {
|
||||
// First 5 rows for GA401 are always 33 physical LEDs long
|
||||
return 33;
|
||||
}
|
||||
36 - y.div_ceil(2)
|
||||
36 - (y + 1) / 2
|
||||
}
|
||||
AnimeType::GU604 => {
|
||||
if y <= 9 {
|
||||
@@ -237,7 +237,7 @@ impl AnimeImage {
|
||||
AnimeType::GA401 => (33.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 {
|
||||
AnimeType::GA401 => 55,
|
||||
AnimeType::GU604 => 62,
|
||||
_ => 61,
|
||||
_ => 61
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ impl AnimeImage {
|
||||
AnimeType::GA401 => (54.0 + 1.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
|
||||
_ => 61.0 * Self::scale_y(anime_type),
|
||||
_ => 61.0 * Self::scale_y(anime_type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,11 +267,11 @@ impl AnimeImage {
|
||||
AnimeType::GA401 => match y {
|
||||
0 | 2 | 4 => 33,
|
||||
1 | 3 => 35, // Some rows are padded
|
||||
_ => 36 - y / 2,
|
||||
_ => 36 - y / 2
|
||||
},
|
||||
AnimeType::GU604 => AnimeImage::width(anime_type, y),
|
||||
// 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));
|
||||
|
||||
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 v in &GROUP {
|
||||
@@ -399,7 +399,7 @@ impl AnimeImage {
|
||||
|
||||
let led_from_cm = Mat3::from_scale(Vec2::new(
|
||||
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 =
|
||||
@@ -422,7 +422,7 @@ impl AnimeImage {
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
bright: f32,
|
||||
anime_type: AnimeType,
|
||||
anime_type: AnimeType
|
||||
) -> Result<Self> {
|
||||
let data = std::fs::read(path).map_err(|e| {
|
||||
error!("Could not open {path:?}: {e:?}");
|
||||
@@ -466,7 +466,7 @@ impl AnimeImage {
|
||||
width = ras.width();
|
||||
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(
|
||||
@@ -476,7 +476,7 @@ impl AnimeImage {
|
||||
bright,
|
||||
pixels,
|
||||
width,
|
||||
anime_type,
|
||||
anime_type
|
||||
)?;
|
||||
|
||||
matrix.update();
|
||||
@@ -485,7 +485,7 @@ impl AnimeImage {
|
||||
|
||||
fn pixels_from_8bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
||||
where
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>,
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>
|
||||
{
|
||||
ras.pixels()
|
||||
.iter()
|
||||
@@ -497,14 +497,14 @@ impl AnimeImage {
|
||||
+ (<u8>::from(px.two()) / 3) as u32
|
||||
+ (<u8>::from(px.three()) / 3) as u32
|
||||
},
|
||||
alpha: <f32>::from(px.alpha()),
|
||||
alpha: <f32>::from(px.alpha())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn pixels_from_16bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
||||
where
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>,
|
||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>
|
||||
{
|
||||
ras.pixels()
|
||||
.iter()
|
||||
@@ -516,7 +516,7 @@ impl AnimeImage {
|
||||
+ ((<u16>::from(px.two()) / 3) >> 8) as u32
|
||||
+ ((<u16>::from(px.three()) / 3) >> 8) as u32
|
||||
},
|
||||
alpha: <f32>::from(px.alpha()),
|
||||
alpha: <f32>::from(px.alpha())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -653,7 +653,7 @@ mod tests {
|
||||
Vec2::default(),
|
||||
AnimTime::Infinite,
|
||||
1.0,
|
||||
AnimeType::GA402,
|
||||
AnimeType::GA402
|
||||
)
|
||||
.unwrap();
|
||||
matrix.frames()[0].frame();
|
||||
|
||||
@@ -16,13 +16,13 @@ pub enum ActionLoader {
|
||||
AsusAnimation {
|
||||
file: PathBuf,
|
||||
time: AnimTime,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
},
|
||||
/// Image designed to be pixel perfect using the slanted template
|
||||
AsusImage {
|
||||
file: PathBuf,
|
||||
time: AnimTime,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
},
|
||||
/// Animated gif. If the file is a png a static gif is created using the
|
||||
/// `time` properties
|
||||
@@ -32,7 +32,7 @@ pub enum ActionLoader {
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
time: AnimTime,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
},
|
||||
Image {
|
||||
file: PathBuf,
|
||||
@@ -40,10 +40,10 @@ pub enum ActionLoader {
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
time: AnimTime,
|
||||
brightness: f32,
|
||||
brightness: f32
|
||||
},
|
||||
/// 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
|
||||
@@ -64,7 +64,7 @@ pub enum ActionData {
|
||||
/// Placeholder
|
||||
TimeDate,
|
||||
/// Placeholder
|
||||
Matrix,
|
||||
Matrix
|
||||
}
|
||||
|
||||
impl ActionData {
|
||||
@@ -73,14 +73,14 @@ impl ActionData {
|
||||
ActionLoader::AsusAnimation {
|
||||
file,
|
||||
time,
|
||||
brightness,
|
||||
brightness
|
||||
} => ActionData::Animation(AnimeGif::from_diagonal_gif(
|
||||
file, *time, *brightness, anime_type,
|
||||
file, *time, *brightness, anime_type
|
||||
)?),
|
||||
ActionLoader::AsusImage {
|
||||
file,
|
||||
time,
|
||||
brightness,
|
||||
brightness
|
||||
} => match time {
|
||||
AnimTime::Infinite => {
|
||||
let image = AnimeDiagonal::from_png(file, None, *brightness, anime_type)?;
|
||||
@@ -88,8 +88,8 @@ impl ActionData {
|
||||
ActionData::Image(Box::new(data))
|
||||
}
|
||||
_ => ActionData::Animation(AnimeGif::from_diagonal_png(
|
||||
file, anime_type, *time, *brightness,
|
||||
)?),
|
||||
file, anime_type, *time, *brightness
|
||||
)?)
|
||||
},
|
||||
ActionLoader::ImageAnimation {
|
||||
file,
|
||||
@@ -97,17 +97,17 @@ impl ActionData {
|
||||
angle,
|
||||
translation,
|
||||
time,
|
||||
brightness,
|
||||
brightness
|
||||
} => {
|
||||
if let Some(ext) = file.extension() {
|
||||
if ext.to_string_lossy().to_lowercase() == "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(
|
||||
file, *scale, *angle, *translation, *time, *brightness, anime_type,
|
||||
file, *scale, *angle, *translation, *time, *brightness, anime_type
|
||||
)?)
|
||||
}
|
||||
ActionLoader::Image {
|
||||
@@ -116,23 +116,23 @@ impl ActionData {
|
||||
angle,
|
||||
translation,
|
||||
brightness,
|
||||
time,
|
||||
time
|
||||
} => {
|
||||
match time {
|
||||
AnimTime::Infinite => {
|
||||
// If no time then create a plain static image
|
||||
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)?;
|
||||
ActionData::Image(Box::new(data))
|
||||
}
|
||||
_ => 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)
|
||||
}
|
||||
@@ -171,7 +171,7 @@ impl Sequences {
|
||||
pub fn iter(&self) -> ActionIterator<'_> {
|
||||
ActionIterator {
|
||||
actions: self,
|
||||
next_idx: 0,
|
||||
next_idx: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ impl Sequences {
|
||||
/// Iteractor helper for iterating over all the actions in `Sequences`
|
||||
pub struct ActionIterator<'a> {
|
||||
actions: &'a Sequences,
|
||||
next_idx: usize,
|
||||
next_idx: usize
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ActionIterator<'a> {
|
||||
|
||||
@@ -35,7 +35,7 @@ pub enum Brightness {
|
||||
Low = 1,
|
||||
#[default]
|
||||
Med = 2,
|
||||
High = 3,
|
||||
High = 3
|
||||
}
|
||||
|
||||
impl FromStr for Brightness {
|
||||
@@ -47,7 +47,7 @@ impl FromStr for Brightness {
|
||||
"Low" | "low" => Brightness::Low,
|
||||
"Med" | "med" => Brightness::Med,
|
||||
"High" | "high" => Brightness::High,
|
||||
_ => Brightness::Med,
|
||||
_ => Brightness::Med
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ impl From<u8> for Brightness {
|
||||
0 => Brightness::Off,
|
||||
1 => Brightness::Low,
|
||||
3 => Brightness::High,
|
||||
_ => Brightness::Med,
|
||||
_ => Brightness::Med
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ impl From<Brightness> for i32 {
|
||||
pub enum AnimBooting {
|
||||
#[default]
|
||||
GlitchConstruction = 0,
|
||||
StaticEmergence = 1,
|
||||
StaticEmergence = 1
|
||||
}
|
||||
|
||||
impl FromStr for AnimBooting {
|
||||
@@ -94,7 +94,7 @@ impl FromStr for AnimBooting {
|
||||
match s {
|
||||
"GlitchConstruction" => Ok(Self::GlitchConstruction),
|
||||
"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 {
|
||||
0 => Self::GlitchConstruction,
|
||||
1 => Self::StaticEmergence,
|
||||
_ => Self::default(),
|
||||
_ => Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ impl From<AnimBooting> for i32 {
|
||||
pub enum AnimAwake {
|
||||
#[default]
|
||||
BinaryBannerScroll = 0,
|
||||
RogLogoGlitch = 1,
|
||||
RogLogoGlitch = 1
|
||||
}
|
||||
|
||||
impl FromStr for AnimAwake {
|
||||
@@ -134,7 +134,7 @@ impl FromStr for AnimAwake {
|
||||
match s {
|
||||
"BinaryBannerScroll" => Ok(Self::BinaryBannerScroll),
|
||||
"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 {
|
||||
0 => Self::BinaryBannerScroll,
|
||||
1 => Self::RogLogoGlitch,
|
||||
_ => Self::default(),
|
||||
_ => Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ impl From<AnimAwake> for i32 {
|
||||
pub enum AnimSleeping {
|
||||
#[default]
|
||||
BannerSwipe = 0,
|
||||
Starfield = 1,
|
||||
Starfield = 1
|
||||
}
|
||||
|
||||
impl FromStr for AnimSleeping {
|
||||
@@ -174,7 +174,7 @@ impl FromStr for AnimSleeping {
|
||||
match s {
|
||||
"BannerSwipe" => Ok(Self::BannerSwipe),
|
||||
"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 {
|
||||
0 => Self::BannerSwipe,
|
||||
1 => Self::Starfield,
|
||||
_ => Self::default(),
|
||||
_ => Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ impl From<AnimSleeping> for i32 {
|
||||
pub enum AnimShutdown {
|
||||
#[default]
|
||||
GlitchOut = 0,
|
||||
SeeYa = 1,
|
||||
SeeYa = 1
|
||||
}
|
||||
|
||||
impl FromStr for AnimShutdown {
|
||||
@@ -214,7 +214,7 @@ impl FromStr for AnimShutdown {
|
||||
match s {
|
||||
"GlitchOut" => Ok(Self::GlitchOut),
|
||||
"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 {
|
||||
0 => Self::GlitchOut,
|
||||
1 => Self::SeeYa,
|
||||
_ => Self::default(),
|
||||
_ => Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,7 @@ impl From<AnimShutdown> for i32 {
|
||||
#[inline]
|
||||
pub fn get_anime_type() -> AnimeType {
|
||||
let dmi = DMIID::new().unwrap_or_default();
|
||||
let board_name = dmi.board_name.to_uppercase();
|
||||
let board_name = dmi.board_name;
|
||||
|
||||
if board_name.contains("GA401I") || board_name.contains("GA401Q") {
|
||||
AnimeType::GA401
|
||||
@@ -251,10 +251,6 @@ pub fn get_anime_type() -> AnimeType {
|
||||
AnimeType::GA402
|
||||
} else if board_name.contains("GU604V") {
|
||||
AnimeType::GU604
|
||||
} else if board_name.contains("G635L") {
|
||||
AnimeType::G635L
|
||||
} else if board_name.contains("G835L") {
|
||||
AnimeType::G835L
|
||||
} else {
|
||||
AnimeType::Unsupported
|
||||
}
|
||||
@@ -330,7 +326,7 @@ pub const fn pkt_set_builtin_animations(
|
||||
boot: AnimBooting,
|
||||
awake: AnimAwake,
|
||||
sleep: AnimSleeping,
|
||||
shutdown: AnimShutdown,
|
||||
shutdown: AnimShutdown
|
||||
) -> [u8; PACKET_SIZE] {
|
||||
let mut pkt = [0; PACKET_SIZE];
|
||||
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, 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, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
let pkt1_check = [
|
||||
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, 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,
|
||||
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(
|
||||
@@ -110,7 +110,7 @@ mod tests {
|
||||
0.0,
|
||||
vec![Pixel::default(); 1000],
|
||||
100,
|
||||
AnimeType::GA401,
|
||||
AnimeType::GA401
|
||||
)
|
||||
.unwrap();
|
||||
matrix.edge_outline();
|
||||
@@ -175,7 +175,7 @@ mod tests {
|
||||
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, 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 = [
|
||||
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, 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,
|
||||
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"));
|
||||
|
||||
@@ -52,7 +52,7 @@ mod tests {
|
||||
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, 0x00, 0x00, 0x00, 0x00, 0x00, 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 = [
|
||||
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,
|
||||
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
let pkt2_check = [
|
||||
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
|
||||
];
|
||||
|
||||
let mut matrix = AnimeImage::new(
|
||||
@@ -158,7 +158,7 @@ mod tests {
|
||||
0.0,
|
||||
vec![Pixel::default(); 1000],
|
||||
100,
|
||||
AnimeType::GA402,
|
||||
AnimeType::GA402
|
||||
)
|
||||
.unwrap();
|
||||
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, 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
|
||||
];
|
||||
let pkt1_check = [
|
||||
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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
let pkt2_check = [
|
||||
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
|
||||
];
|
||||
|
||||
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 = [
|
||||
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, 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 = [
|
||||
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
|
||||
];
|
||||
|
||||
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, 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
|
||||
];
|
||||
let pkt1_check = [
|
||||
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, 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 = [
|
||||
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
|
||||
];
|
||||
|
||||
let mut matrix = AnimeImage::new(
|
||||
@@ -158,7 +158,7 @@ mod tests {
|
||||
0.0,
|
||||
vec![Pixel::default(); 1000],
|
||||
100,
|
||||
AnimeType::GU604,
|
||||
AnimeType::GU604
|
||||
)
|
||||
.unwrap();
|
||||
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, 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
|
||||
];
|
||||
let pkt1_check = [
|
||||
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, 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, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
let pkt2_check = [
|
||||
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
|
||||
];
|
||||
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -14,7 +14,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -23,7 +23,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -32,43 +32,16 @@
|
||||
layout_name: "fa507",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "FA617NS",
|
||||
product_id: "",
|
||||
layout_name: "fa507",
|
||||
layout_name: "fa617ns",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
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,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -77,7 +50,7 @@
|
||||
layout_name: "fx505d",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -86,7 +59,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -95,7 +68,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -104,7 +77,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -113,25 +86,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
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]),
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -140,7 +95,7 @@
|
||||
layout_name: "fa506i",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -149,16 +104,7 @@
|
||||
layout_name: "fx505d",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
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,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -167,7 +113,7 @@
|
||||
layout_name: "g512",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -185,7 +131,7 @@
|
||||
layout_name: "g513i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -206,15 +152,6 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G513RC",
|
||||
product_id: "",
|
||||
layout_name: "g513i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: Zoned([ZonedKbLeft, ZonedKbLeftMid, ZonedKbRightMid, ZonedKbRight, LightbarRight, LightbarRightCorner, LightbarRightBottom, LightbarLeftBottom, LightbarLeftCorner, LightbarLeft]),
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G513RW",
|
||||
product_id: "",
|
||||
@@ -224,13 +161,22 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G513RC",
|
||||
product_id: "",
|
||||
layout_name: "g513i",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: Zoned([ZonedKbLeft, ZonedKbLeftMid, ZonedKbRightMid, ZonedKbRight, LightbarRight, LightbarRightCorner, LightbarRightBottom, LightbarLeftBottom, LightbarLeftCorner, LightbarLeft]),
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G531G",
|
||||
product_id: "",
|
||||
layout_name: "gx502",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -239,7 +185,7 @@
|
||||
layout_name: "gx502",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -278,31 +224,13 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "G614FR",
|
||||
product_id: "",
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
),
|
||||
(
|
||||
device_name: "G614J",
|
||||
product_id: "",
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: 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,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -311,25 +239,16 @@
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G614JU",
|
||||
product_id: "",
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
),
|
||||
(
|
||||
device_name: "G614JZ",
|
||||
product_id: "",
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -341,22 +260,13 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
||||
),
|
||||
(
|
||||
device_name: "G635L",
|
||||
product_id: "",
|
||||
layout_name: "g635l-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
),
|
||||
(
|
||||
device_name: "G712LI",
|
||||
product_id: "",
|
||||
layout_name: "gl503",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -365,7 +275,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -374,7 +284,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -383,7 +293,7 @@
|
||||
layout_name: "gx502",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -392,7 +302,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -401,7 +311,7 @@
|
||||
layout_name: "gx502",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -410,7 +320,7 @@
|
||||
layout_name: "gx502",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -446,7 +356,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -464,7 +374,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
@@ -482,7 +392,7 @@
|
||||
layout_name: "g533q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -491,7 +401,7 @@
|
||||
layout_name: "g533q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -500,7 +410,7 @@
|
||||
layout_name: "g533q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -548,15 +458,6 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G815L",
|
||||
product_id: "",
|
||||
layout_name: "g814ji-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G834J",
|
||||
product_id: "",
|
||||
@@ -572,7 +473,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -581,7 +482,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -590,7 +491,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -599,7 +500,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -608,7 +509,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -617,7 +518,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -626,7 +527,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -635,7 +536,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -644,7 +545,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -653,7 +554,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -662,7 +563,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -680,7 +581,7 @@
|
||||
layout_name: "gl503",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -689,7 +590,7 @@
|
||||
layout_name: "gl503",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -698,7 +599,7 @@
|
||||
layout_name: "gl503",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -716,7 +617,7 @@
|
||||
layout_name: "g533q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -725,7 +626,7 @@
|
||||
layout_name: "gl503",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -734,7 +635,7 @@
|
||||
layout_name: "fa507",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -782,15 +683,6 @@
|
||||
advanced_type: Zoned([SingleZone]),
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "GU605C",
|
||||
product_id: "",
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: Zoned([SingleZone]),
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "GU605M",
|
||||
product_id: "",
|
||||
@@ -806,7 +698,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -815,7 +707,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -824,7 +716,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -833,7 +725,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -851,7 +743,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -869,7 +761,7 @@
|
||||
layout_name: "gx531-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -923,7 +815,7 @@
|
||||
layout_name: "gx531-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -932,7 +824,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -941,7 +833,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -950,8 +842,8 @@
|
||||
layout_name: "",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
power_zones: [r#None],
|
||||
advanced_type: None,
|
||||
power_zones: [None],
|
||||
),
|
||||
(
|
||||
device_name: "GZ301Z",
|
||||
@@ -959,7 +851,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
@@ -968,7 +860,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Ally],
|
||||
),
|
||||
(
|
||||
@@ -977,7 +869,7 @@
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
advanced_type: None,
|
||||
power_zones: [Ally],
|
||||
),
|
||||
])
|
||||
|
||||
@@ -1,375 +0,0 @@
|
||||
(
|
||||
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)]
|
||||
pub advanced_type: AdvancedAuraType,
|
||||
/// If empty will default to `Keyboard` power zone
|
||||
pub power_zones: Vec<PowerZones>,
|
||||
pub power_zones: Vec<PowerZones>
|
||||
}
|
||||
|
||||
impl LedSupportData {
|
||||
@@ -116,7 +116,7 @@ impl LedSupportFile {
|
||||
basic_modes: vec![AuraModeNum::Static],
|
||||
basic_zones: vec![],
|
||||
advanced_type: AdvancedAuraType::None,
|
||||
power_zones: vec![PowerZones::Keyboard],
|
||||
power_zones: vec![PowerZones::Keyboard]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,25 +164,6 @@ impl LedSupportFile {
|
||||
return Some(data);
|
||||
}
|
||||
|
||||
// If the system-wide files were not found (typical in CI or
|
||||
// development environments), attempt to load the bundled
|
||||
// `data/aura_support.ron` from the crate so tests and local runs
|
||||
// behave the same as when the package is installed.
|
||||
// Attempt to load a bundled `aura_support.ron` included at compile time.
|
||||
// Using `include_str!` ensures the data is available regardless of
|
||||
// runtime `CARGO_MANIFEST_DIR` or CI environment differences.
|
||||
let bundled_buf = include_str!("../data/aura_support.ron");
|
||||
if !bundled_buf.is_empty() {
|
||||
if let Ok(tmp) = ron::from_str::<LedSupportFile>(bundled_buf) {
|
||||
data.0.append(&mut tmp.0.clone());
|
||||
data.0.sort_by(|a, b| a.device_name.cmp(&b.device_name));
|
||||
info!("Loaded bundled LED support data (embedded)");
|
||||
return Some(data);
|
||||
} else {
|
||||
warn!("Could not parse embedded bundled data file");
|
||||
}
|
||||
}
|
||||
|
||||
warn!("Does {} exist?", ASUS_LED_MODE_USER_CONF);
|
||||
None
|
||||
}
|
||||
@@ -219,7 +200,7 @@ mod tests {
|
||||
power_zones: vec![
|
||||
PowerZones::Keyboard,
|
||||
PowerZones::RearGlow,
|
||||
],
|
||||
]
|
||||
};
|
||||
|
||||
assert!(ron::to_string(&led).is_ok());
|
||||
|
||||
@@ -19,7 +19,7 @@ pub enum LedBrightness {
|
||||
Low = 1,
|
||||
#[default]
|
||||
Med = 2,
|
||||
High = 3,
|
||||
High = 3
|
||||
}
|
||||
|
||||
impl LedBrightness {
|
||||
@@ -28,7 +28,7 @@ impl LedBrightness {
|
||||
Self::Off => Self::Low,
|
||||
Self::Low => Self::Med,
|
||||
Self::Med => Self::High,
|
||||
Self::High => Self::Off,
|
||||
Self::High => Self::Off
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ impl LedBrightness {
|
||||
Self::Off => Self::High,
|
||||
Self::Low => Self::Off,
|
||||
Self::Med => Self::Low,
|
||||
Self::High => Self::Med,
|
||||
Self::High => Self::Med
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ impl From<u8> for LedBrightness {
|
||||
0 => LedBrightness::Off,
|
||||
1 => LedBrightness::Low,
|
||||
3 => LedBrightness::High,
|
||||
_ => LedBrightness::Med,
|
||||
_ => LedBrightness::Med
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ impl From<i32> for LedBrightness {
|
||||
1 => LedBrightness::Low,
|
||||
2 => LedBrightness::Med,
|
||||
3 => LedBrightness::High,
|
||||
_ => LedBrightness::Med,
|
||||
_ => LedBrightness::Med
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ impl From<i32> for LedBrightness {
|
||||
pub struct Colour {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
pub b: u8,
|
||||
pub b: u8
|
||||
}
|
||||
|
||||
impl Default for Colour {
|
||||
@@ -110,7 +110,7 @@ impl From<&[f32; 3]> for Colour {
|
||||
Self {
|
||||
r: (255.0 * c[0]) 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.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 {
|
||||
r: c[0],
|
||||
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] {
|
||||
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,
|
||||
#[default]
|
||||
Med = 0xeb,
|
||||
High = 0xf5,
|
||||
High = 0xf5
|
||||
}
|
||||
|
||||
impl FromStr for Speed {
|
||||
@@ -165,7 +165,7 @@ impl FromStr for Speed {
|
||||
"low" => Ok(Speed::Low),
|
||||
"med" => Ok(Speed::Med),
|
||||
"high" => Ok(Speed::High),
|
||||
_ => Err(Error::ParseSpeed),
|
||||
_ => Err(Error::ParseSpeed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ impl From<i32> for Speed {
|
||||
match value {
|
||||
0 => Self::Low,
|
||||
2 => Self::High,
|
||||
_ => Self::Med,
|
||||
_ => Self::Med
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ impl From<Speed> for i32 {
|
||||
match value {
|
||||
Speed::Low => 0,
|
||||
Speed::Med => 1,
|
||||
Speed::High => 2,
|
||||
Speed::High => 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ impl From<Speed> for u8 {
|
||||
match s {
|
||||
Speed::Low => 0,
|
||||
Speed::Med => 1,
|
||||
Speed::High => 2,
|
||||
Speed::High => 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ pub enum Direction {
|
||||
Right = 0,
|
||||
Left = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
Down = 3
|
||||
}
|
||||
|
||||
impl FromStr for Direction {
|
||||
@@ -226,7 +226,7 @@ impl FromStr for Direction {
|
||||
"up" => Ok(Direction::Up),
|
||||
"down" => Ok(Direction::Down),
|
||||
"left" => Ok(Direction::Left),
|
||||
_ => Err(Error::ParseDirection),
|
||||
_ => Err(Error::ParseDirection)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,7 +237,7 @@ impl From<i32> for Direction {
|
||||
1 => Self::Left,
|
||||
2 => Self::Up,
|
||||
3 => Self::Down,
|
||||
_ => Self::Right,
|
||||
_ => Self::Right
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +270,7 @@ pub enum AuraModeNum {
|
||||
Ripple = 8,
|
||||
Pulse = 10,
|
||||
Comet = 11,
|
||||
Flash = 12,
|
||||
Flash = 12
|
||||
}
|
||||
|
||||
impl Display for AuraModeNum {
|
||||
@@ -299,7 +299,7 @@ impl From<&AuraModeNum> for &str {
|
||||
AuraModeNum::Ripple => "Ripple",
|
||||
AuraModeNum::Pulse => "Pulse",
|
||||
AuraModeNum::Comet => "Comet",
|
||||
AuraModeNum::Flash => "Flash",
|
||||
AuraModeNum::Flash => "Flash"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ impl From<&str> for AuraModeNum {
|
||||
"Pulse" => AuraModeNum::Pulse,
|
||||
"Comet" => AuraModeNum::Comet,
|
||||
"Flash" => AuraModeNum::Flash,
|
||||
_ => AuraModeNum::Static,
|
||||
_ => AuraModeNum::Static
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,7 +336,7 @@ impl From<u8> for AuraModeNum {
|
||||
10 => AuraModeNum::Pulse,
|
||||
11 => AuraModeNum::Comet,
|
||||
12 => AuraModeNum::Flash,
|
||||
_ => AuraModeNum::Static,
|
||||
_ => AuraModeNum::Static
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,12 +359,6 @@ impl From<AuraEffect> for AuraModeNum {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "dbus")]
|
||||
impl zbus::zvariant::Basic for AuraModeNum {
|
||||
const SIGNATURE_CHAR: char = 'u';
|
||||
const SIGNATURE_STR: &'static str = "u";
|
||||
}
|
||||
|
||||
/// Base effects have no zoning, while multizone is 1-4
|
||||
#[cfg_attr(
|
||||
feature = "dbus",
|
||||
@@ -389,7 +383,7 @@ pub enum AuraZone {
|
||||
/// The left part of a lightbar (typically on the front of laptop)
|
||||
BarLeft = 6,
|
||||
/// The right part of a lightbar
|
||||
BarRight = 7,
|
||||
BarRight = 7
|
||||
}
|
||||
|
||||
impl FromStr for AuraZone {
|
||||
@@ -406,7 +400,7 @@ impl FromStr for AuraZone {
|
||||
"5" | "logo" => Ok(AuraZone::Logo),
|
||||
"6" | "lightbar-left" => Ok(AuraZone::BarLeft),
|
||||
"7" | "lightbar-right" => Ok(AuraZone::BarRight),
|
||||
_ => Err(Error::ParseSpeed),
|
||||
_ => Err(Error::ParseSpeed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -421,7 +415,7 @@ impl From<i32> for AuraZone {
|
||||
5 => Self::Logo,
|
||||
6 => Self::BarLeft,
|
||||
7 => Self::BarRight,
|
||||
_ => Self::default(),
|
||||
_ => Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -451,7 +445,7 @@ pub struct AuraEffect {
|
||||
/// One of three speeds for modes that support speed (most that animate)
|
||||
pub speed: Speed,
|
||||
/// Up, down, left, right. Only Rainbow mode seems to use this
|
||||
pub direction: Direction,
|
||||
pub direction: Direction
|
||||
}
|
||||
|
||||
impl AuraEffect {
|
||||
@@ -487,7 +481,7 @@ impl Default for AuraEffect {
|
||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right,
|
||||
direction: Direction::Right
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -547,7 +541,7 @@ impl From<&AuraEffect> for Vec<u8> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
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]
|
||||
@@ -558,18 +552,18 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0xff,
|
||||
g: 0x11,
|
||||
b: 0xdd,
|
||||
b: 0xdd
|
||||
},
|
||||
colour2: Colour::default(),
|
||||
speed: Speed::Med,
|
||||
direction: Direction::Right,
|
||||
direction: Direction::Right
|
||||
};
|
||||
let ar = <[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st);
|
||||
|
||||
println!("{:02x?}", ar);
|
||||
let check = [
|
||||
0x5d, 0xb3, 0x0, 0x0, 0xff, 0x11, 0xdd, 0xeb, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
0x0
|
||||
];
|
||||
assert_eq!(ar, check);
|
||||
}
|
||||
@@ -582,15 +576,15 @@ mod tests {
|
||||
colour1: Colour {
|
||||
r: 0xff,
|
||||
g: 0,
|
||||
b: 0,
|
||||
b: 0
|
||||
},
|
||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||
speed: Speed::Low,
|
||||
direction: Direction::Left,
|
||||
direction: Direction::Left
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -601,11 +595,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0xff,
|
||||
g: 0xff,
|
||||
b: 0,
|
||||
b: 0
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x02, 0x00, 0xff, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -616,11 +610,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0,
|
||||
g: 0xff,
|
||||
b: 0xff,
|
||||
b: 0xff
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -631,11 +625,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0xff,
|
||||
b: 0xff
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x04, 0x00, 0xff, 0x00, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -646,11 +640,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0x2c,
|
||||
g: 0xff,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x05, 0x00, 0x2c, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -661,11 +655,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x06, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -676,11 +670,11 @@ mod tests {
|
||||
st.colour1 = Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0xcd,
|
||||
b: 0xcd
|
||||
};
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x07, 0x00, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
@@ -690,7 +684,7 @@ mod tests {
|
||||
st.mode = AuraModeNum::RainbowWave;
|
||||
let capture = [
|
||||
0x5d, 0xb3, 0x07, 0x03, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0
|
||||
];
|
||||
assert_eq!(
|
||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||
|
||||
@@ -11,7 +11,7 @@ pub struct InputBased {
|
||||
/// - temperature
|
||||
/// - fan speed
|
||||
/// - time
|
||||
input: Box<dyn InputForEffect>,
|
||||
input: Box<dyn InputForEffect>
|
||||
}
|
||||
|
||||
impl EffectState for InputBased {
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct Breathe {
|
||||
#[serde(skip)]
|
||||
count_flipped: bool,
|
||||
#[serde(skip)]
|
||||
use_colour1: bool,
|
||||
use_colour1: bool
|
||||
}
|
||||
|
||||
impl Breathe {
|
||||
@@ -31,7 +31,7 @@ impl Breathe {
|
||||
speed,
|
||||
colour: colour1,
|
||||
count_flipped: false,
|
||||
use_colour1: true,
|
||||
use_colour1: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct DoomFlicker {
|
||||
#[serde(skip)]
|
||||
count: u8,
|
||||
#[serde(skip)]
|
||||
colour: Colour,
|
||||
colour: Colour
|
||||
}
|
||||
|
||||
impl DoomFlicker {
|
||||
@@ -24,7 +24,7 @@ impl DoomFlicker {
|
||||
count: 4,
|
||||
max_percentage,
|
||||
min_percentage,
|
||||
start_colour: colour,
|
||||
start_colour: colour
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,13 +53,13 @@ impl EffectState for DoomFlicker {
|
||||
let max_light = Colour {
|
||||
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,
|
||||
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
|
||||
let min_light = Colour {
|
||||
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,
|
||||
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
|
||||
@@ -96,7 +96,7 @@ pub struct DoomLightFlash {
|
||||
#[serde(skip)]
|
||||
count: u8,
|
||||
#[serde(skip)]
|
||||
colour: Colour,
|
||||
colour: Colour
|
||||
}
|
||||
|
||||
impl DoomLightFlash {
|
||||
@@ -109,7 +109,7 @@ impl DoomLightFlash {
|
||||
min_percentage,
|
||||
start_colour: colour,
|
||||
max_time: 32,
|
||||
min_time: 7,
|
||||
min_time: 7
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,13 +135,13 @@ impl EffectState for DoomLightFlash {
|
||||
let max_light = Colour {
|
||||
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,
|
||||
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
|
||||
let min_light = Colour {
|
||||
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,
|
||||
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 {
|
||||
|
||||
@@ -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,
|
||||
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,
|
||||
84, 118, 222, 187, 136, 120, 163, 236, 249,
|
||||
84, 118, 222, 187, 136, 120, 163, 236, 249
|
||||
];
|
||||
|
||||
pub fn p_random() -> i32 {
|
||||
@@ -67,7 +67,7 @@ pub(crate) trait EffectState {
|
||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||
pub struct AdvancedEffects {
|
||||
effects: Vec<Effect>,
|
||||
zoned: bool,
|
||||
zoned: bool
|
||||
}
|
||||
|
||||
impl AdvancedEffects {
|
||||
@@ -75,7 +75,7 @@ impl AdvancedEffects {
|
||||
pub fn new(zoned: bool) -> Self {
|
||||
Self {
|
||||
effects: Default::default(),
|
||||
zoned,
|
||||
zoned
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ pub enum Effect {
|
||||
Static(Static),
|
||||
Breathe(Breathe),
|
||||
DoomFlicker(DoomFlicker),
|
||||
DoomLightFlash(DoomLightFlash),
|
||||
DoomLightFlash(DoomLightFlash)
|
||||
}
|
||||
|
||||
impl Default for Effect {
|
||||
@@ -207,14 +207,12 @@ mod tests {
|
||||
fn single_key_next_state_then_create() {
|
||||
let layout = KeyLayout::default_layout();
|
||||
let mut seq = AdvancedEffects::new(false);
|
||||
seq.effects.push(Effect::Static(Static::new(
|
||||
LedCode::F,
|
||||
Colour {
|
||||
seq.effects
|
||||
.push(Effect::Static(Static::new(LedCode::F, Colour {
|
||||
r: 255,
|
||||
g: 127,
|
||||
b: 0,
|
||||
},
|
||||
)));
|
||||
b: 0
|
||||
})));
|
||||
|
||||
seq.next_state(&layout);
|
||||
let packets = seq.create_packets();
|
||||
@@ -234,14 +232,14 @@ mod tests {
|
||||
Colour {
|
||||
r: 255,
|
||||
g: 127,
|
||||
b: 0,
|
||||
b: 0
|
||||
},
|
||||
Colour {
|
||||
r: 127,
|
||||
g: 0,
|
||||
b: 255,
|
||||
b: 255
|
||||
},
|
||||
Speed::Med,
|
||||
Speed::Med
|
||||
)));
|
||||
|
||||
let s =
|
||||
@@ -276,10 +274,10 @@ mod tests {
|
||||
Colour {
|
||||
r: 255,
|
||||
g: 127,
|
||||
b: 80,
|
||||
b: 80
|
||||
},
|
||||
100,
|
||||
10,
|
||||
10
|
||||
)));
|
||||
|
||||
seq.next_state(&layout);
|
||||
|
||||
@@ -8,14 +8,14 @@ use crate::{effect_state_impl, Colour};
|
||||
pub struct Static {
|
||||
led: LedCode,
|
||||
/// The starting colour
|
||||
colour: Colour,
|
||||
colour: Colour
|
||||
}
|
||||
|
||||
impl Static {
|
||||
pub fn new(address: LedCode, colour: Colour) -> Self {
|
||||
Self {
|
||||
led: address,
|
||||
colour,
|
||||
colour
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ pub enum Error {
|
||||
ParseBrightness,
|
||||
IoPath(String, std::io::Error),
|
||||
Ron(ron::Error),
|
||||
RonParse(ron::error::SpannedError),
|
||||
RonParse(ron::error::SpannedError)
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -21,7 +21,7 @@ impl fmt::Display for Error {
|
||||
Error::ParseBrightness => write!(f, "Could not parse brightness"),
|
||||
Error::IoPath(path, io) => write!(f, "IO Error: {path}, {io}"),
|
||||
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
|
||||
Spacing,
|
||||
/// To be ignored by effects
|
||||
Blocking,
|
||||
Blocking
|
||||
}
|
||||
|
||||
impl LedCode {
|
||||
@@ -210,7 +210,7 @@ pub struct LedUsbPackets {
|
||||
/// Wether or not this packet collection is zoned. The determines which
|
||||
/// starting bytes are used and what the indexing is for lightbar RGB
|
||||
/// colours
|
||||
zoned: bool,
|
||||
zoned: bool
|
||||
}
|
||||
|
||||
impl Default for LedUsbPackets {
|
||||
@@ -244,7 +244,7 @@ impl LedUsbPackets {
|
||||
}
|
||||
Self {
|
||||
usb_packets: set,
|
||||
zoned: false,
|
||||
zoned: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ impl LedUsbPackets {
|
||||
}
|
||||
Self {
|
||||
usb_packets: vec![pkt],
|
||||
zoned: true,
|
||||
zoned: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ impl From<&LedCode> for &str {
|
||||
LedCode::ZonedKbLeft => "Left Zone (zone 1)",
|
||||
LedCode::ZonedKbLeftMid => "Center-left Zone (zone 2)",
|
||||
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_right: f32,
|
||||
pad_top: f32,
|
||||
pad_bottom: f32,
|
||||
pad_bottom: f32
|
||||
},
|
||||
Blank {
|
||||
width: f32,
|
||||
height: f32,
|
||||
},
|
||||
height: f32
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyShape {
|
||||
@@ -41,7 +41,7 @@ impl KeyShape {
|
||||
pad_left: f32,
|
||||
pad_right: f32,
|
||||
pad_top: f32,
|
||||
pad_bottom: f32,
|
||||
pad_bottom: f32
|
||||
) -> Self {
|
||||
Self::Led {
|
||||
width,
|
||||
@@ -49,7 +49,7 @@ impl KeyShape {
|
||||
pad_left,
|
||||
pad_right,
|
||||
pad_top,
|
||||
pad_bottom,
|
||||
pad_bottom
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ impl KeyShape {
|
||||
pad_left,
|
||||
pad_right,
|
||||
pad_top,
|
||||
pad_bottom,
|
||||
pad_bottom
|
||||
} => {
|
||||
*width *= scale;
|
||||
*height *= scale;
|
||||
@@ -97,7 +97,7 @@ pub struct KeyRow {
|
||||
row: Vec<(LedCode, String)>,
|
||||
/// The final data structure merged key_shapes and rows
|
||||
#[serde(skip)]
|
||||
built_row: Vec<(LedCode, KeyShape)>,
|
||||
built_row: Vec<(LedCode, KeyShape)>
|
||||
}
|
||||
|
||||
impl KeyRow {
|
||||
@@ -106,7 +106,7 @@ impl KeyRow {
|
||||
pad_left,
|
||||
pad_top,
|
||||
row,
|
||||
built_row: Default::default(),
|
||||
built_row: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ impl KeyRow {
|
||||
pad_bottom,
|
||||
..
|
||||
} => height + pad_top + pad_bottom,
|
||||
KeyShape::Blank { height, .. } => *height,
|
||||
KeyShape::Blank { height, .. } => *height
|
||||
};
|
||||
|
||||
if h < height {
|
||||
@@ -156,7 +156,7 @@ impl KeyRow {
|
||||
pad_right,
|
||||
..
|
||||
} => w += width + pad_left + pad_right,
|
||||
KeyShape::Blank { width, .. } => w += width,
|
||||
KeyShape::Blank { width, .. } => w += width
|
||||
}
|
||||
}
|
||||
w
|
||||
@@ -185,7 +185,7 @@ pub struct KeyLayout {
|
||||
/// Should be copied from the `LaptopLedData` as laptops may have the same
|
||||
/// layout, but different EC features.
|
||||
#[serde(skip)]
|
||||
advanced_type: AdvancedAuraType,
|
||||
advanced_type: AdvancedAuraType
|
||||
}
|
||||
|
||||
impl KeyLayout {
|
||||
@@ -195,7 +195,7 @@ impl KeyLayout {
|
||||
if buf.is_empty() {
|
||||
Err(Error::IoPath(
|
||||
path.to_string_lossy().to_string(),
|
||||
std::io::ErrorKind::InvalidData.into(),
|
||||
std::io::ErrorKind::InvalidData.into()
|
||||
))
|
||||
} else {
|
||||
let mut data = ron::from_str::<Self>(&buf)?;
|
||||
@@ -332,121 +332,97 @@ impl KeyLayout {
|
||||
advanced_type: AdvancedAuraType::None,
|
||||
key_shapes: HashMap::from([(
|
||||
"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![
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::Esc, "regular".to_owned()),
|
||||
(LedCode::F1, "regular".to_owned()),
|
||||
(LedCode::F2, "regular".to_owned()),
|
||||
(LedCode::F3, "regular".to_owned()),
|
||||
(LedCode::F4, "regular".to_owned()),
|
||||
// not sure which key to put here
|
||||
(LedCode::F5, "regular".to_owned()),
|
||||
(LedCode::F6, "regular".to_owned()),
|
||||
(LedCode::F7, "regular".to_owned()),
|
||||
(LedCode::F8, "regular".to_owned()),
|
||||
(LedCode::F9, "regular".to_owned()),
|
||||
(LedCode::F10, "regular".to_owned()),
|
||||
(LedCode::F11, "regular".to_owned()),
|
||||
(LedCode::F12, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::Tilde, "regular".to_owned()),
|
||||
(LedCode::N1, "regular".to_owned()),
|
||||
(LedCode::N2, "regular".to_owned()),
|
||||
(LedCode::N3, "regular".to_owned()),
|
||||
(LedCode::N4, "regular".to_owned()),
|
||||
(LedCode::N5, "regular".to_owned()),
|
||||
(LedCode::N6, "regular".to_owned()),
|
||||
(LedCode::N7, "regular".to_owned()),
|
||||
(LedCode::N8, "regular".to_owned()),
|
||||
(LedCode::N9, "regular".to_owned()),
|
||||
(LedCode::N0, "regular".to_owned()),
|
||||
(LedCode::Hyphen, "regular".to_owned()),
|
||||
(LedCode::Equals, "regular".to_owned()),
|
||||
(LedCode::Backspace, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::Tab, "regular".to_owned()),
|
||||
(LedCode::Q, "regular".to_owned()),
|
||||
(LedCode::W, "regular".to_owned()),
|
||||
(LedCode::E, "regular".to_owned()),
|
||||
(LedCode::R, "regular".to_owned()),
|
||||
(LedCode::T, "regular".to_owned()),
|
||||
(LedCode::Y, "regular".to_owned()),
|
||||
(LedCode::U, "regular".to_owned()),
|
||||
(LedCode::I, "regular".to_owned()),
|
||||
(LedCode::O, "regular".to_owned()),
|
||||
(LedCode::P, "regular".to_owned()),
|
||||
(LedCode::LBracket, "regular".to_owned()),
|
||||
(LedCode::RBracket, "regular".to_owned()),
|
||||
(LedCode::BackSlash, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::Caps, "regular".to_owned()),
|
||||
(LedCode::A, "regular".to_owned()),
|
||||
(LedCode::S, "regular".to_owned()),
|
||||
(LedCode::D, "regular".to_owned()),
|
||||
(LedCode::F, "regular".to_owned()),
|
||||
(LedCode::G, "regular".to_owned()),
|
||||
(LedCode::H, "regular".to_owned()),
|
||||
(LedCode::J, "regular".to_owned()),
|
||||
(LedCode::K, "regular".to_owned()),
|
||||
(LedCode::L, "regular".to_owned()),
|
||||
(LedCode::SemiColon, "regular".to_owned()),
|
||||
(LedCode::Quote, "regular".to_owned()),
|
||||
(LedCode::Return, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::LShift, "regular".to_owned()),
|
||||
(LedCode::Z, "regular".to_owned()),
|
||||
(LedCode::X, "regular".to_owned()),
|
||||
(LedCode::C, "regular".to_owned()),
|
||||
(LedCode::V, "regular".to_owned()),
|
||||
(LedCode::B, "regular".to_owned()),
|
||||
(LedCode::N, "regular".to_owned()),
|
||||
(LedCode::M, "regular".to_owned()),
|
||||
(LedCode::Comma, "regular".to_owned()),
|
||||
(LedCode::Period, "regular".to_owned()),
|
||||
(LedCode::FwdSlash, "regular".to_owned()),
|
||||
(LedCode::Rshift, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
KeyRow::new(
|
||||
0.1,
|
||||
0.1,
|
||||
vec![
|
||||
(LedCode::LCtrl, "regular".to_owned()),
|
||||
(LedCode::LFn, "regular".to_owned()),
|
||||
(LedCode::Meta, "regular".to_owned()),
|
||||
(LedCode::LAlt, "regular".to_owned()),
|
||||
(LedCode::Spacebar, "regular".to_owned()),
|
||||
(LedCode::RAlt, "regular".to_owned()),
|
||||
(LedCode::PrtSc, "regular".to_owned()),
|
||||
(LedCode::RCtrl, "regular".to_owned()),
|
||||
],
|
||||
),
|
||||
],
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::Esc, "regular".to_owned()),
|
||||
(LedCode::F1, "regular".to_owned()),
|
||||
(LedCode::F2, "regular".to_owned()),
|
||||
(LedCode::F3, "regular".to_owned()),
|
||||
(LedCode::F4, "regular".to_owned()),
|
||||
// not sure which key to put here
|
||||
(LedCode::F5, "regular".to_owned()),
|
||||
(LedCode::F6, "regular".to_owned()),
|
||||
(LedCode::F7, "regular".to_owned()),
|
||||
(LedCode::F8, "regular".to_owned()),
|
||||
(LedCode::F9, "regular".to_owned()),
|
||||
(LedCode::F10, "regular".to_owned()),
|
||||
(LedCode::F11, "regular".to_owned()),
|
||||
(LedCode::F12, "regular".to_owned()),
|
||||
]),
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::Tilde, "regular".to_owned()),
|
||||
(LedCode::N1, "regular".to_owned()),
|
||||
(LedCode::N2, "regular".to_owned()),
|
||||
(LedCode::N3, "regular".to_owned()),
|
||||
(LedCode::N4, "regular".to_owned()),
|
||||
(LedCode::N5, "regular".to_owned()),
|
||||
(LedCode::N6, "regular".to_owned()),
|
||||
(LedCode::N7, "regular".to_owned()),
|
||||
(LedCode::N8, "regular".to_owned()),
|
||||
(LedCode::N9, "regular".to_owned()),
|
||||
(LedCode::N0, "regular".to_owned()),
|
||||
(LedCode::Hyphen, "regular".to_owned()),
|
||||
(LedCode::Equals, "regular".to_owned()),
|
||||
(LedCode::Backspace, "regular".to_owned()),
|
||||
]),
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::Tab, "regular".to_owned()),
|
||||
(LedCode::Q, "regular".to_owned()),
|
||||
(LedCode::W, "regular".to_owned()),
|
||||
(LedCode::E, "regular".to_owned()),
|
||||
(LedCode::R, "regular".to_owned()),
|
||||
(LedCode::T, "regular".to_owned()),
|
||||
(LedCode::Y, "regular".to_owned()),
|
||||
(LedCode::U, "regular".to_owned()),
|
||||
(LedCode::I, "regular".to_owned()),
|
||||
(LedCode::O, "regular".to_owned()),
|
||||
(LedCode::P, "regular".to_owned()),
|
||||
(LedCode::LBracket, "regular".to_owned()),
|
||||
(LedCode::RBracket, "regular".to_owned()),
|
||||
(LedCode::BackSlash, "regular".to_owned()),
|
||||
]),
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::Caps, "regular".to_owned()),
|
||||
(LedCode::A, "regular".to_owned()),
|
||||
(LedCode::S, "regular".to_owned()),
|
||||
(LedCode::D, "regular".to_owned()),
|
||||
(LedCode::F, "regular".to_owned()),
|
||||
(LedCode::G, "regular".to_owned()),
|
||||
(LedCode::H, "regular".to_owned()),
|
||||
(LedCode::J, "regular".to_owned()),
|
||||
(LedCode::K, "regular".to_owned()),
|
||||
(LedCode::L, "regular".to_owned()),
|
||||
(LedCode::SemiColon, "regular".to_owned()),
|
||||
(LedCode::Quote, "regular".to_owned()),
|
||||
(LedCode::Return, "regular".to_owned()),
|
||||
]),
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::LShift, "regular".to_owned()),
|
||||
(LedCode::Z, "regular".to_owned()),
|
||||
(LedCode::X, "regular".to_owned()),
|
||||
(LedCode::C, "regular".to_owned()),
|
||||
(LedCode::V, "regular".to_owned()),
|
||||
(LedCode::B, "regular".to_owned()),
|
||||
(LedCode::N, "regular".to_owned()),
|
||||
(LedCode::M, "regular".to_owned()),
|
||||
(LedCode::Comma, "regular".to_owned()),
|
||||
(LedCode::Period, "regular".to_owned()),
|
||||
(LedCode::FwdSlash, "regular".to_owned()),
|
||||
(LedCode::Rshift, "regular".to_owned()),
|
||||
]),
|
||||
KeyRow::new(0.1, 0.1, vec![
|
||||
(LedCode::LCtrl, "regular".to_owned()),
|
||||
(LedCode::LFn, "regular".to_owned()),
|
||||
(LedCode::Meta, "regular".to_owned()),
|
||||
(LedCode::LAlt, "regular".to_owned()),
|
||||
(LedCode::Spacebar, "regular".to_owned()),
|
||||
(LedCode::RAlt, "regular".to_owned()),
|
||||
(LedCode::PrtSc, "regular".to_owned()),
|
||||
(LedCode::RCtrl, "regular".to_owned()),
|
||||
]),
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,5 +16,5 @@ pub enum AdvancedAuraType {
|
||||
#[default]
|
||||
None,
|
||||
Zoned(Vec<LedCode>),
|
||||
PerKey,
|
||||
PerKey
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct AuraPowerState {
|
||||
pub awake: bool,
|
||||
pub sleep: bool,
|
||||
/// Ignored for pre-2021 and Tuf
|
||||
pub shutdown: bool,
|
||||
pub shutdown: bool
|
||||
}
|
||||
|
||||
impl Default for AuraPowerState {
|
||||
@@ -34,7 +34,7 @@ impl Default for AuraPowerState {
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ impl AuraPowerState {
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ impl AuraPowerState {
|
||||
| ((self.sleep as u32) << (23 + 3))
|
||||
| ((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))]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct LaptopAuraPower {
|
||||
pub states: Vec<AuraPowerState>,
|
||||
pub states: Vec<AuraPowerState>
|
||||
}
|
||||
|
||||
impl LaptopAuraPower {
|
||||
@@ -206,19 +206,19 @@ impl LaptopAuraPower {
|
||||
// 3. KeyboardAndLightbar
|
||||
if support_data.power_zones.contains(&PowerZones::Lightbar) {
|
||||
Self {
|
||||
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)],
|
||||
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)]
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)]
|
||||
}
|
||||
}
|
||||
}
|
||||
AuraDeviceType::LaptopKeyboardTuf => Self {
|
||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)]
|
||||
},
|
||||
AuraDeviceType::ScsiExtDisk => todo!(),
|
||||
AuraDeviceType::AnimeOrSlash => todo!(),
|
||||
AuraDeviceType::AnimeOrSlash => todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ impl LaptopAuraPower {
|
||||
self.new_to_bytes()
|
||||
}
|
||||
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,
|
||||
Sleep = 0x300804,
|
||||
Keyboard = 0x080000,
|
||||
Lightbar = 0x040500,
|
||||
Lightbar = 0x040500
|
||||
}
|
||||
|
||||
impl BitOr<OldAuraPower> for OldAuraPower {
|
||||
@@ -332,9 +332,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
};
|
||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||
@@ -347,9 +347,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
};
|
||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||
@@ -369,16 +369,16 @@ mod test {
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
AuraPowerState {
|
||||
zone: PowerZones::Lightbar,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
};
|
||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||
@@ -394,9 +394,9 @@ mod test {
|
||||
boot: true,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let boot_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -405,9 +405,9 @@ mod test {
|
||||
boot: true,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let sleep_logo = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -416,9 +416,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let sleep_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -427,9 +427,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let awake_logo = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -438,9 +438,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let awake_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -449,9 +449,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let shut_logo_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -460,9 +460,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let shut_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -471,9 +471,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let boot_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -482,9 +482,9 @@ mod test {
|
||||
boot: true,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let awake_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -493,9 +493,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let sleep_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -504,9 +504,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let shut_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -515,9 +515,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let boot_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -526,9 +526,9 @@ mod test {
|
||||
boot: true,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let awake_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -537,9 +537,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let sleep_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -548,9 +548,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let shut_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -559,9 +559,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let boot_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -570,9 +570,9 @@ mod test {
|
||||
boot: true,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let awake_rear = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -581,9 +581,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: true,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let sleep_rear = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -592,9 +592,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: true,
|
||||
shutdown: false,
|
||||
shutdown: false
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
let shut_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||
states: vec![
|
||||
@@ -603,9 +603,9 @@ mod test {
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: true,
|
||||
shutdown: true
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
|
||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||
@@ -655,7 +655,7 @@ mod test {
|
||||
zone: PowerZones::RearGlow,
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
]
|
||||
});
|
||||
assert_eq!(byte1, "11111111, 00011110, 00001111, 00001111");
|
||||
}
|
||||
|
||||
@@ -29,40 +29,40 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const RED: Colour = Colour {
|
||||
r: 0xff,
|
||||
g: 0x00,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
pub const GREEN: Colour = Colour {
|
||||
r: 0x00,
|
||||
g: 0xff,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
pub const BLUE: Colour = Colour {
|
||||
r: 0x00,
|
||||
g: 0x00,
|
||||
b: 0xff,
|
||||
b: 0xff
|
||||
};
|
||||
pub const VIOLET: Colour = Colour {
|
||||
r: 0x9b,
|
||||
g: 0x26,
|
||||
b: 0xb6,
|
||||
b: 0xb6
|
||||
};
|
||||
pub const TEAL: Colour = Colour {
|
||||
r: 0x00,
|
||||
g: 0x7c,
|
||||
b: 0x80,
|
||||
b: 0x80
|
||||
};
|
||||
pub const YELLOW: Colour = Colour {
|
||||
r: 0xff,
|
||||
g: 0xef,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
pub const ORANGE: Colour = Colour {
|
||||
r: 0xff,
|
||||
g: 0xa4,
|
||||
b: 0x00,
|
||||
b: 0x00
|
||||
};
|
||||
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))]
|
||||
@@ -76,7 +76,7 @@ pub enum AuraDeviceType {
|
||||
ScsiExtDisk = 3,
|
||||
Ally = 4,
|
||||
AnimeOrSlash = 5,
|
||||
Unknown = 255,
|
||||
Unknown = 255
|
||||
}
|
||||
|
||||
impl AuraDeviceType {
|
||||
@@ -110,7 +110,7 @@ impl From<&str> for AuraDeviceType {
|
||||
"1abe" | "1b4c" => Self::Ally,
|
||||
"19b3" | "193b" => Self::AnimeOrSlash,
|
||||
"19b6" => Self::LaptopKeyboard2021,
|
||||
_ => Self::Unknown,
|
||||
_ => Self::Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,5 +138,5 @@ pub enum PowerZones {
|
||||
KeyboardAndLightbar = 5,
|
||||
/// Ally specific for creating correct packet
|
||||
Ally = 6,
|
||||
None = 255,
|
||||
None = 255
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Only these two packets must be 17 bytes
|
||||
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] = [
|
||||
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 = []
|
||||
mocking = []
|
||||
x11 = ["slint/backend-winit-x11"]
|
||||
# Optional tokio debug feature does not require nightly; remove RUSTFLAGS note.
|
||||
# Requires RUSTFLAGS="--cfg tokio_unstable"
|
||||
tokio-debug = ["console-subscriber"]
|
||||
|
||||
[dependencies]
|
||||
@@ -49,26 +49,12 @@ versions.workspace = true
|
||||
git = "https://github.com/slint-ui/slint.git"
|
||||
default-features = false
|
||||
features = [
|
||||
"compat-1-2",
|
||||
"gettext",
|
||||
"compat-1-2",
|
||||
"backend-winit-wayland",
|
||||
"renderer-femtovg",
|
||||
"renderer-winit-femtovg",
|
||||
# "renderer-skia-opengl",
|
||||
]
|
||||
|
||||
[build-dependencies.slint-build]
|
||||
git = "https://github.com/slint-ui/slint.git"
|
||||
|
||||
[package.metadata.deb]
|
||||
license-file = ["../LICENSE", "4"]
|
||||
extended-description = """\
|
||||
The dbus server for asusctl and rog-control-center applications."""
|
||||
depends = "$auto"
|
||||
section = "utility"
|
||||
priority = "optional"
|
||||
assets = [
|
||||
["target/release/rog-control-center", "usr/bin/", "755"],
|
||||
["../rog_gui-fakeinstall/usr/share/applications/*", "usr/share/share/applications/", "644"],
|
||||
["../rog_gui-fakeinstall/usr/share/icons/hicolor/512x512/apps/*", "usr/share/icons/hicolor/512x512/apps", "644"],
|
||||
["../rog_gui-fakeinstall/usr/share/icons/hicolor/scalable/status/*", "usr/share/icons/hicolor/scalable/status", "644"],
|
||||
]
|
||||
|
||||
@@ -18,7 +18,7 @@ fn main() {
|
||||
CompilerConfiguration::new()
|
||||
// .embed_resources(EmbedResourcesKind::EmbedFiles)
|
||||
.with_include_paths(vec![include])
|
||||
.with_style("fluent".into()),
|
||||
.with_style("fluent".into())
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -23,5 +23,5 @@ pub struct CliStart {
|
||||
help = "put ROGCC in layout viewing mode - this is helpful for finding existing layouts \
|
||||
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_height: u32,
|
||||
// This field must be last
|
||||
pub notifications: EnabledNotifications,
|
||||
pub notifications: EnabledNotifications
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@@ -36,7 +36,7 @@ impl Default for Config {
|
||||
fullscreen_height: 1080,
|
||||
notifications: EnabledNotifications::default(),
|
||||
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 dark_mode: bool,
|
||||
// This field must be last
|
||||
pub enabled_notifications: EnabledNotifications,
|
||||
pub enabled_notifications: EnabledNotifications
|
||||
}
|
||||
|
||||
impl From<Config461> for Config {
|
||||
@@ -92,7 +92,7 @@ impl From<Config461> for Config {
|
||||
start_fullscreen: false,
|
||||
fullscreen_width: 1920,
|
||||
fullscreen_height: 1080,
|
||||
notifications: c.enabled_notifications,
|
||||
notifications: c.enabled_notifications
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ pub enum Error {
|
||||
ConfigLockFail,
|
||||
XdgVars,
|
||||
Zbus(zbus::Error),
|
||||
ZbusFdo(zbus::fdo::Error),
|
||||
Notification(notify_rust::error::Error),
|
||||
Notification(notify_rust::error::Error)
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -22,8 +21,7 @@ impl fmt::Display for Error {
|
||||
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||
Error::Zbus(err) => write!(f, "Error: {}", err),
|
||||
Error::ZbusFdo(err) => write!(f, "Error: {}", err),
|
||||
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
||||
Error::Notification(err) => write!(f, "Notification Error: {}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,12 +40,6 @@ 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 {
|
||||
fn from(err: notify_rust::error::Error) -> Self {
|
||||
Error::Notification(err)
|
||||
|
||||
@@ -38,5 +38,5 @@ pub enum Page {
|
||||
System,
|
||||
AuraEffects,
|
||||
AnimeMatrix,
|
||||
FanCurves,
|
||||
FanCurves
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::time::Duration;
|
||||
use config_traits::{StdConfig, StdConfigLoad1};
|
||||
use dmi_id::DMIID;
|
||||
use gumdrop::Options;
|
||||
use log::{debug, info, warn, LevelFilter};
|
||||
use log::{info, warn, LevelFilter};
|
||||
use rog_control_center::cli_options::CliStart;
|
||||
use rog_control_center::config::Config;
|
||||
use rog_control_center::error::Result;
|
||||
@@ -17,42 +17,25 @@ use rog_control_center::slint::ComponentHandle;
|
||||
use rog_control_center::tray::init_tray;
|
||||
use rog_control_center::ui::setup_window;
|
||||
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 tokio::runtime::Runtime;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Ensure tracing spans are quiet by default unless user overrides
|
||||
if std::env::var_os("RUST_LOG").is_none() {
|
||||
std::env::set_var("RUST_LOG", "warn,tracing=error,zbus=error");
|
||||
}
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
.filter_level(LevelFilter::Warn)
|
||||
.parse_default_env()
|
||||
.filter_level(LevelFilter::Info)
|
||||
.parse_default_env()
|
||||
.target(env_logger::Target::Stderr)
|
||||
.target(env_logger::Target::Stdout)
|
||||
.format_timestamp(None)
|
||||
.init();
|
||||
|
||||
// If we're running under gamescope we have to set WAYLAND_DISPLAY for winit to
|
||||
// use
|
||||
if let Ok(gamescope) = env::var("GAMESCOPE_WAYLAND_DISPLAY") {
|
||||
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");
|
||||
}
|
||||
}
|
||||
env::set_var("WAYLAND_DISPLAY", gamescope);
|
||||
}
|
||||
|
||||
// Try to open a proxy and check for app state first
|
||||
@@ -80,7 +63,7 @@ async fn main() -> Result<()> {
|
||||
.unwrap();
|
||||
if asusd_version != self_version {
|
||||
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||
// return Ok(());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// start tokio
|
||||
@@ -107,7 +90,7 @@ async fn main() -> Result<()> {
|
||||
let board_name = dmi.board_name;
|
||||
let prod_family = dmi.product_family;
|
||||
info!("Running on {board_name}, product: {prod_family}");
|
||||
let is_rog_ally = board_name == "RC71L" || board_name == "RC72L" || prod_family == "ROG Ally";
|
||||
let is_rog_ally = prod_family == "RC71L" || prod_family == "RC72L";
|
||||
|
||||
let args: Vec<String> = args().skip(1).collect();
|
||||
|
||||
@@ -178,101 +161,73 @@ async fn main() -> Result<()> {
|
||||
thread::spawn(move || {
|
||||
let mut state = AppState::StartingUp;
|
||||
loop {
|
||||
if is_rog_ally {
|
||||
let config_copy_2 = config.clone();
|
||||
let newui = setup_window(config.clone());
|
||||
newui.window().on_close_requested(move || {
|
||||
exit(0);
|
||||
});
|
||||
// save as a var, don't hold the lock the entire time or deadlocks happen
|
||||
if let Ok(app_state) = app_state.lock() {
|
||||
state = *app_state;
|
||||
}
|
||||
|
||||
let ui_copy = newui.as_weak();
|
||||
newui
|
||||
.window()
|
||||
.set_rendering_notifier(move |s, _| {
|
||||
if let slint::RenderingState::BeforeRendering = 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);
|
||||
// This sleep is required to give the event loop time to react
|
||||
sleep(Duration::from_millis(300));
|
||||
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);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
} else {
|
||||
// save as a var, don't hold the lock the entire time or deadlocks happen
|
||||
if let Ok(app_state) = app_state.lock() {
|
||||
state = *app_state;
|
||||
}
|
||||
|
||||
// This sleep is required to give the event loop time to react
|
||||
sleep(Duration::from_millis(300));
|
||||
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);
|
||||
}
|
||||
});
|
||||
})
|
||||
.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::supported::{
|
||||
AdvancedAura, AnimeSupportedFunctions, ChargeSupportedFunctions, LedSupportedFunctions,
|
||||
PlatformProfileFunctions, RogBiosSupportedFunctions, SupportedFunctions,
|
||||
PlatformProfileFunctions, RogBiosSupportedFunctions, SupportedFunctions
|
||||
};
|
||||
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
@@ -16,7 +16,7 @@ const NOPE: &str = "";
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DaemonProxyBlocking<'a> {
|
||||
_phantom: &'a str,
|
||||
_phantom: &'a str
|
||||
}
|
||||
|
||||
impl<'a> DaemonProxyBlocking<'a> {
|
||||
@@ -35,7 +35,7 @@ impl<'a> DaemonProxyBlocking<'a> {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RogDbusClientBlocking<'a> {
|
||||
_phantom: &'a str,
|
||||
_phantom: &'a str
|
||||
}
|
||||
|
||||
impl<'a> RogDbusClientBlocking<'a> {
|
||||
@@ -126,16 +126,16 @@ impl Profile {
|
||||
pub fn fan_curve_data(&self, _p: rog_profiles::Profile) -> Result<FanCurveSet> {
|
||||
let mut curve = FanCurveSet::default();
|
||||
curve.cpu.pwm = [
|
||||
30, 40, 60, 100, 140, 180, 200, 250,
|
||||
30, 40, 60, 100, 140, 180, 200, 250
|
||||
];
|
||||
curve.cpu.temp = [
|
||||
20, 30, 40, 50, 70, 80, 90, 100,
|
||||
20, 30, 40, 50, 70, 80, 90, 100
|
||||
];
|
||||
curve.gpu.pwm = [
|
||||
40, 80, 100, 140, 170, 200, 230, 250,
|
||||
40, 80, 100, 140, 170, 200, 230, 250
|
||||
];
|
||||
curve.gpu.temp = [
|
||||
20, 30, 40, 50, 70, 80, 90, 100,
|
||||
20, 30, 40, 50, 70, 80, 90, 100
|
||||
];
|
||||
Ok(curve)
|
||||
}
|
||||
@@ -204,7 +204,7 @@ impl Led {
|
||||
AuraDevRog2::AwakeKeyb,
|
||||
AuraDevRog2::SleepLogo,
|
||||
AuraDevRog2::AwakeLogo,
|
||||
],
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
@@ -242,11 +242,11 @@ impl Supported {
|
||||
Ok(SupportedFunctions {
|
||||
anime_ctrl: AnimeSupportedFunctions(true),
|
||||
charge_ctrl: ChargeSupportedFunctions {
|
||||
charge_level_set: true,
|
||||
charge_level_set: true
|
||||
},
|
||||
platform_profile: PlatformProfileFunctions {
|
||||
platform_profile: true,
|
||||
fan_curves: true,
|
||||
fan_curves: true
|
||||
},
|
||||
keyboard_led: LedSupportedFunctions {
|
||||
dev_id: AuraDevice::X19b6,
|
||||
@@ -267,7 +267,7 @@ impl Supported {
|
||||
AuraZone::BarRight,
|
||||
AuraZone::Logo,
|
||||
],
|
||||
advanced_type: AdvancedAura::PerKey,
|
||||
advanced_type: AdvancedAura::PerKey
|
||||
},
|
||||
rog_bios_ctrl: RogBiosSupportedFunctions {
|
||||
post_sound: true,
|
||||
@@ -275,8 +275,8 @@ impl Supported {
|
||||
panel_overdrive: true,
|
||||
dgpu_disable: true,
|
||||
mini_led_mode: true,
|
||||
egpu_enable: true,
|
||||
},
|
||||
egpu_enable: true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@ use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use log::{debug, error, info, warn};
|
||||
use notify_rust::{Hint, Notification, Timeout};
|
||||
use notify_rust::{Hint, Notification, Timeout, Urgency};
|
||||
use rog_platform::platform::GpuMode;
|
||||
use rog_platform::power::AsusPower;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use supergfxctl::pci_device::GfxPower;
|
||||
use supergfxctl::actions::UserActionRequired as GfxUserAction;
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::task::JoinHandle;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::error::Result;
|
||||
@@ -27,7 +31,7 @@ const NOTIF_HEADER: &str = "ROG Control";
|
||||
pub struct EnabledNotifications {
|
||||
pub enabled: bool,
|
||||
pub receive_notify_gfx: bool,
|
||||
pub receive_notify_gfx_status: bool,
|
||||
pub receive_notify_gfx_status: bool
|
||||
}
|
||||
|
||||
impl Default for EnabledNotifications {
|
||||
@@ -35,7 +39,7 @@ impl Default for EnabledNotifications {
|
||||
Self {
|
||||
enabled: true,
|
||||
receive_notify_gfx: true,
|
||||
receive_notify_gfx_status: true,
|
||||
receive_notify_gfx_status: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +92,7 @@ fn start_dpu_status_mon(config: Arc<Mutex<Config>>) {
|
||||
|
||||
pub fn start_notifications(
|
||||
config: Arc<Mutex<Config>>,
|
||||
rt: &Runtime,
|
||||
rt: &Runtime
|
||||
) -> Result<Vec<JoinHandle<()>>> {
|
||||
// Setup the AC/BAT commands that will run on power status change
|
||||
let config_copy = config.clone();
|
||||
@@ -112,26 +116,26 @@ pub fn start_notifications(
|
||||
|
||||
if p == 0 && p != last_state {
|
||||
let prog: Vec<&str> = bat.split_whitespace().collect();
|
||||
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||
if prog.len() > 1 {
|
||||
let mut cmd = Command::new(prog[0]);
|
||||
|
||||
for arg in prog.iter().skip(1) {
|
||||
cmd.arg(*arg);
|
||||
}
|
||||
cmd.spawn()
|
||||
.map_err(|e| error!("Battery power command error: {e:?}"))
|
||||
.map_err(|e| error!("AC command error: {e:?}"))
|
||||
.ok();
|
||||
}
|
||||
} else if p != last_state {
|
||||
let prog: Vec<&str> = ac.split_whitespace().collect();
|
||||
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||
if prog.len() > 1 {
|
||||
let mut cmd = Command::new(prog[0]);
|
||||
|
||||
for arg in prog.iter().skip(1) {
|
||||
cmd.arg(*arg);
|
||||
}
|
||||
cmd.spawn()
|
||||
.map_err(|e| error!("AC power command error: {e:?}"))
|
||||
.map_err(|e| error!("AC command error: {e:?}"))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
@@ -141,8 +145,12 @@ pub fn start_notifications(
|
||||
}
|
||||
});
|
||||
|
||||
info!("Attempting to start plain dgpu status monitor");
|
||||
start_dpu_status_mon(config.clone());
|
||||
let enabled_notifications_copy = config.clone();
|
||||
let no_supergfx = move |e: &zbus::Error| {
|
||||
error!("zbus signal: receive_notify_gfx_status: {e}");
|
||||
warn!("Attempting to start plain dgpu status monitor");
|
||||
start_dpu_status_mon(enabled_notifications_copy.clone());
|
||||
};
|
||||
|
||||
// GPU MUX Mode notif
|
||||
// TODO: need to get armoury attrs and iter to find
|
||||
@@ -181,12 +189,90 @@ pub fn start_notifications(
|
||||
// Ok::<(), zbus::Error>(())
|
||||
// });
|
||||
|
||||
let enabled_notifications_copy = config.clone();
|
||||
// GPU Mode change/action notif
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system().await.inspect_err(|e| {
|
||||
no_supergfx(e);
|
||||
})?;
|
||||
let proxy = SuperProxy::builder(&conn).build().await.inspect_err(|e| {
|
||||
no_supergfx(e);
|
||||
})?;
|
||||
let _ = proxy.mode().await.inspect_err(|e| {
|
||||
no_supergfx(e);
|
||||
})?;
|
||||
|
||||
let proxy_copy = proxy.clone();
|
||||
let mut p = proxy.receive_notify_action().await?;
|
||||
tokio::spawn(async move {
|
||||
info!("Started zbus signal thread: receive_notify_action");
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
let action = out.action();
|
||||
let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default());
|
||||
match action {
|
||||
supergfxctl::actions::UserActionRequired::Reboot => {
|
||||
do_mux_notification("Graphics mode change requires reboot", &mode)
|
||||
}
|
||||
_ => do_gfx_action_notif(<&str>::from(action), *action, mode)
|
||||
}
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: do_gfx_action_notif: {e}");
|
||||
e
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut p = proxy_copy.receive_notify_gfx_status().await?;
|
||||
tokio::spawn(async move {
|
||||
info!("Started zbus signal thread: receive_notify_gfx_status");
|
||||
let mut last_status = GfxPower::Unknown;
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
let status = out.status;
|
||||
if status != GfxPower::Unknown && status != last_status {
|
||||
if let Ok(config) = enabled_notifications_copy.lock() {
|
||||
if !config.notifications.receive_notify_gfx_status
|
||||
|| !config.notifications.enabled
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Required check because status cycles through
|
||||
// active/unknown/suspended
|
||||
do_gpu_status_notif("dGPU status changed:", &status)
|
||||
.show_async()
|
||||
.await
|
||||
.unwrap()
|
||||
.on_close(|_| ());
|
||||
}
|
||||
last_status = status;
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok::<(), zbus::Error>(())
|
||||
});
|
||||
|
||||
Ok(vec![blocking])
|
||||
}
|
||||
|
||||
fn convert_gfx_mode(gfx: GfxMode) -> GpuMode {
|
||||
match gfx {
|
||||
GfxMode::Hybrid => GpuMode::Optimus,
|
||||
GfxMode::Integrated => GpuMode::Integrated,
|
||||
GfxMode::NvidiaNoModeset => GpuMode::Optimus,
|
||||
GfxMode::Vfio => GpuMode::Vfio,
|
||||
GfxMode::AsusEgpu => GpuMode::Egpu,
|
||||
GfxMode::AsusMuxDgpu => GpuMode::Ultimate,
|
||||
GfxMode::None => GpuMode::Error
|
||||
}
|
||||
}
|
||||
|
||||
fn base_notification<T>(message: &str, data: &T) -> Notification
|
||||
where
|
||||
T: Display,
|
||||
T: Display
|
||||
{
|
||||
let mut notif = Notification::new();
|
||||
notif
|
||||
@@ -204,8 +290,100 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Notification {
|
||||
GfxPower::Off => "asus_notif_green",
|
||||
GfxPower::AsusDisabled => "asus_notif_white",
|
||||
GfxPower::AsusMuxDiscreet | GfxPower::Active => "asus_notif_red",
|
||||
GfxPower::Unknown => "gpu-integrated",
|
||||
GfxPower::Unknown => "gpu-integrated"
|
||||
};
|
||||
notif.icon(icon);
|
||||
notif
|
||||
}
|
||||
|
||||
fn do_gfx_action_notif(message: &str, action: GfxUserAction, mode: GpuMode) -> Result<()> {
|
||||
if matches!(action, GfxUserAction::Reboot) {
|
||||
do_mux_notification("Graphics mode change requires reboot", &mode).ok();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut notif = Notification::new();
|
||||
notif
|
||||
.appname(NOTIF_HEADER)
|
||||
.summary(&format!("Changing to {mode}. {message}"))
|
||||
//.hint(Hint::Resident(true))
|
||||
.hint(Hint::Category("device".into()))
|
||||
.urgency(Urgency::Critical)
|
||||
.timeout(Timeout::Never)
|
||||
.icon("dialog-warning")
|
||||
.hint(Hint::Transient(true));
|
||||
|
||||
if matches!(action, GfxUserAction::Logout) {
|
||||
notif.action("gfx-mode-session-action", "Logout");
|
||||
let handle = notif.show()?;
|
||||
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||
if desktop.to_lowercase() == "gnome" {
|
||||
handle.wait_for_action(|id| {
|
||||
if id == "gfx-mode-session-action" {
|
||||
let mut cmd = Command::new("gnome-session-quit");
|
||||
cmd.spawn().ok();
|
||||
} else if id == "__closed" {
|
||||
// TODO: cancel the switching
|
||||
}
|
||||
});
|
||||
} else if desktop.to_lowercase() == "kde" {
|
||||
handle.wait_for_action(|id| {
|
||||
if id == "gfx-mode-session-action" {
|
||||
let mut cmd = Command::new("qdbus");
|
||||
cmd.args([
|
||||
"org.kde.ksmserver", "/KSMServer", "logout", "1", "0", "0"
|
||||
]);
|
||||
cmd.spawn().ok();
|
||||
} else if id == "__closed" {
|
||||
// TODO: cancel the switching
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// todo: handle alternatives
|
||||
}
|
||||
}
|
||||
} else {
|
||||
notif.show()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Actual `GpuMode` unused as data is never correct until switched by reboot
|
||||
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
|
||||
let mut notif = base_notification(message, &m.to_string());
|
||||
notif
|
||||
.action("gfx-mode-session-action", "Reboot")
|
||||
.urgency(Urgency::Critical)
|
||||
.icon("system-reboot-symbolic")
|
||||
.hint(Hint::Transient(true));
|
||||
let handle = notif.show()?;
|
||||
|
||||
std::thread::spawn(|| {
|
||||
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||
if desktop.to_lowercase() == "gnome" {
|
||||
handle.wait_for_action(|id| {
|
||||
if id == "gfx-mode-session-action" {
|
||||
let mut cmd = Command::new("gnome-session-quit");
|
||||
cmd.arg("--reboot");
|
||||
cmd.spawn().ok();
|
||||
} else if id == "__closed" {
|
||||
// TODO: cancel the switching
|
||||
}
|
||||
});
|
||||
} else if desktop.to_lowercase() == "kde" {
|
||||
handle.wait_for_action(|id| {
|
||||
if id == "gfx-mode-session-action" {
|
||||
let mut cmd = Command::new("qdbus");
|
||||
cmd.args([
|
||||
"org.kde.ksmserver", "/KSMServer", "logout", "1", "1", "0"
|
||||
]);
|
||||
cmd.spawn().ok();
|
||||
} else if id == "__closed" {
|
||||
// TODO: cancel the switching
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ struct Icons {
|
||||
rog_red: Icon,
|
||||
rog_green: Icon,
|
||||
rog_white: Icon,
|
||||
gpu_integrated: Icon,
|
||||
gpu_integrated: Icon
|
||||
}
|
||||
|
||||
static ICONS: OnceLock<Icons> = OnceLock::new();
|
||||
@@ -32,10 +32,7 @@ static ICONS: OnceLock<Icons> = OnceLock::new();
|
||||
fn read_icon(file: &Path) -> Icon {
|
||||
let mut path = PathBuf::from(TRAY_ICON_PATH);
|
||||
path.push(file);
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&path)
|
||||
.unwrap_or_else(|_| panic!("Missing icon: {:?}", path));
|
||||
let mut file = OpenOptions::new().read(true).open(path).unwrap();
|
||||
let mut bytes = Vec::new();
|
||||
file.read_to_end(&mut bytes).unwrap();
|
||||
|
||||
@@ -51,14 +48,14 @@ fn read_icon(file: &Path) -> Icon {
|
||||
Icon {
|
||||
width: width as i32,
|
||||
height: height as i32,
|
||||
data: img.into_raw(),
|
||||
data: img.into_raw()
|
||||
}
|
||||
}
|
||||
|
||||
struct AsusTray {
|
||||
current_title: String,
|
||||
current_icon: Icon,
|
||||
proxy: ROGCCZbusProxyBlocking<'static>,
|
||||
proxy: ROGCCZbusProxyBlocking<'static>
|
||||
}
|
||||
|
||||
impl ksni::Tray for AsusTray {
|
||||
@@ -106,7 +103,7 @@ async fn set_tray_icon_and_tip(
|
||||
mode: GfxMode,
|
||||
power: GfxPower,
|
||||
tray: &mut Handle<AsusTray>,
|
||||
supergfx_active: bool,
|
||||
supergfx_active: bool
|
||||
) {
|
||||
if let Some(icons) = ICONS.get() {
|
||||
let icon = match power {
|
||||
@@ -165,12 +162,12 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
||||
let tray_init = AsusTray {
|
||||
current_title: TRAY_LABEL.to_string(),
|
||||
current_icon: rog_red.clone(),
|
||||
proxy,
|
||||
proxy
|
||||
};
|
||||
|
||||
// TODO: return an error to the UI
|
||||
let mut tray;
|
||||
match tray_init.disable_dbus_name(true).spawn().await {
|
||||
match tray_init.spawn_without_dbus_name().await {
|
||||
Ok(t) => tray = t,
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
@@ -190,7 +187,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
||||
rog_red: rog_red.clone(),
|
||||
rog_green,
|
||||
rog_white,
|
||||
gpu_integrated,
|
||||
gpu_integrated
|
||||
});
|
||||
|
||||
let mut has_supergfx = false;
|
||||
@@ -218,8 +215,8 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
||||
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");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::slint_generatedMainWindow::{
|
||||
AuraDevType as SlintDeviceType, AuraPowerState as SlintAuraPowerState,
|
||||
LaptopAuraPower as SlintLaptopAuraPower,
|
||||
LaptopAuraPower as SlintLaptopAuraPower
|
||||
};
|
||||
|
||||
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,
|
||||
green: m.colour1.g,
|
||||
blue: m.colour1.b,
|
||||
alpha: 255,
|
||||
alpha: 255
|
||||
}
|
||||
.into(),
|
||||
colour2: RgbaColor {
|
||||
red: m.colour2.r,
|
||||
green: m.colour2.g,
|
||||
blue: m.colour2.b,
|
||||
alpha: 255,
|
||||
alpha: 255
|
||||
}
|
||||
.into(),
|
||||
direction: m.direction.into(),
|
||||
mode: m.mode.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 {
|
||||
r: c1.red,
|
||||
g: c1.green,
|
||||
b: c1.blue,
|
||||
b: c1.blue
|
||||
},
|
||||
colour2: rog_aura::Colour {
|
||||
r: c2.red,
|
||||
g: c2.green,
|
||||
b: c2.blue,
|
||||
b: c2.blue
|
||||
},
|
||||
direction: m.direction.into(),
|
||||
mode: m.mode.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::KeyboardAndLightbar => SlintPowerZones::KeyboardAndLightbar,
|
||||
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::RearGlow => PowerZones::RearGlow,
|
||||
SlintPowerZones::KeyboardAndLightbar => PowerZones::KeyboardAndLightbar,
|
||||
SlintPowerZones::Ally => PowerZones::Ally,
|
||||
SlintPowerZones::Ally => PowerZones::Ally
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ impl From<SlintAuraPowerState> for AuraPowerState {
|
||||
boot: value.boot,
|
||||
awake: value.awake,
|
||||
sleep: value.sleep,
|
||||
shutdown: value.shutdown,
|
||||
shutdown: value.shutdown
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ impl From<AuraPowerState> for SlintAuraPowerState {
|
||||
sleep: value.sleep,
|
||||
shutdown: value.shutdown,
|
||||
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,
|
||||
shutdown: value.shutdown,
|
||||
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> =
|
||||
value.states.iter().map(SlintAuraPowerState::from).collect();
|
||||
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::Unknown => Self::Unknown,
|
||||
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::Unknown => SlintDeviceType::Unknown,
|
||||
AuraDeviceType::Ally => SlintDeviceType::Ally,
|
||||
AuraDeviceType::AnimeOrSlash => SlintDeviceType::AnimeOrSlash,
|
||||
AuraDeviceType::AnimeOrSlash => SlintDeviceType::AnimeOrSlash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ impl From<Profile> for PlatformProfile {
|
||||
match value {
|
||||
Profile::Balanced => PlatformProfile::Balanced,
|
||||
Profile::Performance => PlatformProfile::Performance,
|
||||
Profile::Quiet => PlatformProfile::Quiet,
|
||||
Profile::LowPower => PlatformProfile::LowPower,
|
||||
Profile::Custom => PlatformProfile::Custom,
|
||||
Profile::Quiet => PlatformProfile::Quiet
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +18,7 @@ impl From<PlatformProfile> for Profile {
|
||||
match value {
|
||||
PlatformProfile::Balanced => Profile::Balanced,
|
||||
PlatformProfile::Performance => Profile::Performance,
|
||||
PlatformProfile::Quiet => Profile::Quiet,
|
||||
PlatformProfile::LowPower => Profile::LowPower,
|
||||
PlatformProfile::Custom => Profile::Custom,
|
||||
PlatformProfile::Quiet => Profile::Quiet
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +28,7 @@ impl From<FanType> for FanCurvePU {
|
||||
match value {
|
||||
FanType::CPU => FanCurvePU::CPU,
|
||||
FanType::Middle => FanCurvePU::MID,
|
||||
FanType::GPU => FanCurvePU::GPU,
|
||||
FanType::GPU => FanCurvePU::GPU
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +38,7 @@ impl From<FanCurvePU> for FanType {
|
||||
match value {
|
||||
FanCurvePU::CPU => FanType::CPU,
|
||||
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 {
|
||||
let mut x = proxy_copy.receive().await;
|
||||
concat_idents::concat_idents!(set = set_, $proxy_fn {
|
||||
use futures_util::StreamExt;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
while let Some(e) = x.next().await {
|
||||
if let Ok(out) = e.get().await {
|
||||
handle_copy.upgrade_in_event_loop(move |handle| {
|
||||
@@ -68,7 +68,7 @@ pub fn show_toast(
|
||||
success: SharedString,
|
||||
fail: SharedString,
|
||||
handle: Weak<MainWindow>,
|
||||
result: zbus::Result<()>,
|
||||
result: zbus::Result<()>
|
||||
) {
|
||||
match result {
|
||||
Ok(_) => {
|
||||
@@ -78,7 +78,7 @@ pub fn show_toast(
|
||||
log::warn!("{fail}: {e}");
|
||||
handle.unwrap().invoke_show_toast(fail)
|
||||
})
|
||||
.ok(),
|
||||
.ok()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -86,13 +86,8 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
||||
slint::set_xdg_app_id("rog-control-center")
|
||||
.map_err(|e| warn!("Couldn't set application ID: {e:?}"))
|
||||
.ok();
|
||||
let ui = MainWindow::new()
|
||||
.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 ui = MainWindow::new().unwrap();
|
||||
ui.window().show().unwrap();
|
||||
|
||||
let available = list_iface_blocking().unwrap_or_default();
|
||||
ui.set_sidebar_items_avilable(
|
||||
@@ -103,9 +98,9 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
||||
available.contains(&"xyz.ljones.Anime".to_string()),
|
||||
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
.into(),
|
||||
.into()
|
||||
);
|
||||
|
||||
ui.on_exit_app(move || {
|
||||
|
||||
@@ -51,9 +51,9 @@ pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
boot: boot.into(),
|
||||
awake: awake.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();
|
||||
tokio::spawn(async move {
|
||||
let mut x = anime_copy.receive_builtin_animations_changed().await;
|
||||
use futures_util::StreamExt;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
while let Some(e) = x.next().await {
|
||||
if let Ok(out) = e.get().await {
|
||||
handle_copy
|
||||
|
||||
@@ -9,7 +9,7 @@ use slint::{ComponentHandle, Model, RgbaColor, SharedString};
|
||||
use crate::config::Config;
|
||||
use crate::ui::show_toast;
|
||||
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> {
|
||||
@@ -19,7 +19,7 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
||||
alpha: 255,
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
blue: 0
|
||||
};
|
||||
}
|
||||
let c: Vec<u8> = (0..s.len())
|
||||
@@ -30,7 +30,7 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
||||
alpha: 255,
|
||||
red: *c.first().unwrap_or(&255),
|
||||
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(),
|
||||
"Failed to set Aura power settings".into(),
|
||||
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
|
||||
tokio::spawn(async move {
|
||||
let mut x = proxy_copy.receive_led_mode_data_changed().await;
|
||||
use futures_util::StreamExt;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
while let Some(e) = x.next().await {
|
||||
if let Ok(out) = e.get().await {
|
||||
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