mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
135 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5d5681b49 | |||
| 1c8e50843b | |||
| 487d140bd5 | |||
| 661ea8d3bf | |||
| 28d1ed6ab3 | |||
| 903b978e86 | |||
| 519f6bd46b | |||
| a94a8ca28d | |||
| f9dca2da5d | |||
| df88ff1acb | |||
| cb5aa0f170 | |||
| 4ea79f966e | |||
| b8bc1a01b3 | |||
| 0e5d1815bd | |||
| 64e8cb65d0 | |||
| 3142353f98 | |||
| 484ca692ad | |||
| 1ebdfada96 | |||
| 3bc9dfcda1 | |||
| 895e5d2ca3 | |||
| 564992719e | |||
| a737d240be | |||
| d89c1ebf26 | |||
| be7686bb46 | |||
| 4f70055f85 | |||
| 91ca049298 | |||
| 635d0378ac | |||
| 1c729316f7 | |||
| 4701c019a8 | |||
| ca0d8bda4b | |||
| a271ffbb10 | |||
| 00babaf949 | |||
| 2f844ac151 | |||
| 5178bf1d1a | |||
| 116afb9b6c | |||
| 4468a58487 | |||
| 2f73577e91 | |||
| c1cffc8f59 | |||
| 6d8f85c154 | |||
| 0674e7f61c | |||
| fde2f3ba15 | |||
| 70493d1a93 | |||
| c20d0a76a0 | |||
| e6952e241a | |||
| b40812928a | |||
| 8cdc9773c9 | |||
| 8d30282edf | |||
| 4ba44560a9 | |||
| cdc9ca7b58 | |||
| 7eae7c5664 | |||
| 739a0ffa63 | |||
| 637360095c | |||
| 4b34ab83fb | |||
| ac605cbc00 | |||
| 4b38e5daa6 | |||
| 1c007b4216 | |||
| 193f9dfa1e | |||
| 1366422d96 | |||
| 4e778a3d28 | |||
| be05508110 | |||
| 9119229d41 | |||
| 5c43c31331 | |||
| 014604724f | |||
| 7d076368e9 | |||
| 5d6ed5c365 | |||
| a2b8f0f93c | |||
| 5fe8416c65 | |||
| 1b4d7a95af | |||
| e8627fde4c | |||
| 6b0edc6da1 | |||
| f6ad631a0f | |||
| f6393a3926 | |||
| d51384c3a1 | |||
| 78f18959fb | |||
| 7a661a585e | |||
| f4f7a1e648 | |||
| b6e3e5e823 | |||
| 41b1bd23d6 | |||
| 69458a0595 | |||
| 5fd107df27 | |||
| 2558057e9f | |||
| 8111daaf1d | |||
| 672acb234f | |||
| 9725062fb9 | |||
| c7b1624313 | |||
| 67b97f1d43 | |||
| 6498fd1349 | |||
| e371229b6c | |||
| 0fac33a8ff | |||
| b0da062577 | |||
| ca41bd59de | |||
| efcad3f6f9 | |||
| fa2255cbaf | |||
| 02b9bac899 | |||
| a1fcf5023c | |||
| 2f8ea80e6d | |||
| b798cf6a4e | |||
| 3da848d131 | |||
| a88c33c201 | |||
| 7b0f037cba | |||
| 91b1456d06 | |||
| c3b02a2bb0 | |||
| 8e4b7d53f4 | |||
| a44145f487 | |||
| bb7b3a81fb | |||
| 19607d71c3 | |||
| 96f281d789 | |||
| 7613eded95 | |||
| 50eccd2b1d | |||
| ba54007102 | |||
| a028f5375f | |||
| 9ec02cd727 | |||
| 4b46ece09a | |||
| 086bbd0908 | |||
| c94eaa473e | |||
| b1b809834b | |||
| 84183288ec | |||
| 86cbef83b6 | |||
| 006fb632c4 | |||
| e3636ed8ce | |||
| cfd207f251 | |||
| d4c68546e7 | |||
| 6f4a7e16dc | |||
| f64253d633 | |||
| 124c17aadc | |||
| ab40f9fcbf | |||
| 5cdfa5a8d4 | |||
| ce870cd5ed | |||
| 4541d2e1ba | |||
| b525411fd3 | |||
| a867496f13 | |||
| f421b8ee3b | |||
| 82780feb4b | |||
| 1e5443e206 | |||
| 027a591d26 |
@@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
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'
|
echo '+cargo +nightly fmt --all -- --check'
|
||||||
cargo +nightly fmt --all -- --check
|
cargo +nightly fmt --all -- --check
|
||||||
|
|
||||||
echo '+cargo clippy --all -- -D warnings'
|
echo '+cargo clippy --all -- -D warnings'
|
||||||
cargo clippy --all -- -D warnings
|
cargo clippy --all -- -D warnings
|
||||||
|
|
||||||
echo '+cargo test --all'
|
echo '+cargo test --all'
|
||||||
cargo test --all
|
cargo test --all
|
||||||
|
|
||||||
echo '+cargo cranky'
|
echo '+cargo cranky'
|
||||||
cargo cranky
|
cargo cranky
|
||||||
+4
-3
@@ -17,7 +17,7 @@ image: rust:latest
|
|||||||
- target/release/.cargo-lock
|
- target/release/.cargo-lock
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev libsdl2-dev libsdl2-gfx-dev
|
- apt-get update -qq && apt-get install -y -qq libinput-dev libseat-dev libudev-dev libgtk-3-dev grep llvm clang libclang-dev libsdl2-dev libsdl2-gfx-dev
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- format
|
- format
|
||||||
@@ -59,11 +59,12 @@ release:
|
|||||||
- tags
|
- tags
|
||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
|
- cargo install cargo-vendor-filterer
|
||||||
- make && make vendor
|
- make && make vendor
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- vendor_asusctl*.tar.xz
|
- vendor_asusctl*.tar.xz
|
||||||
- cargo-config
|
- cargo-config
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
## Issue description
|
||||||
|
|
||||||
|
(** I can not support distros which are outdated by default. This includes Ubuntu at least 50% of the time, and definitely includes Mint. **)
|
||||||
|
(Summarize the bug encountered)
|
||||||
|
|
||||||
|
## Steps to reproduce
|
||||||
|
|
||||||
|
(How can the issue be reproduced)
|
||||||
|
|
||||||
|
## What is the current bug behavior?
|
||||||
|
|
||||||
|
(What actually happens)
|
||||||
|
|
||||||
|
## What is the expected correct behavior?
|
||||||
|
|
||||||
|
(What you should see instead)
|
||||||
|
|
||||||
|
## Relevant logs and/or screenshots
|
||||||
|
|
||||||
|
(run `journalctl -b -u asusd > ~/asusd.log` and attach `~/asusd.log`)
|
||||||
|
|
||||||
|
(Paste any relevant logs - use code blocks (```) to format console output, logs, and code, as
|
||||||
|
it's very hard to read otherwise.)
|
||||||
|
|
||||||
|
## System details
|
||||||
|
|
||||||
|
- Distro:
|
||||||
|
- Kernel: (`uname -r`)
|
||||||
|
- Desktop:
|
||||||
|
- Xorg or wayland: ??
|
||||||
|
|
||||||
|
/label ~bug ~reproducable ~needs-investigation
|
||||||
+349
-56
@@ -1,4 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
@@ -6,19 +7,106 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [v5.0.2]
|
## [v6.0.0]
|
||||||
|
|
||||||
|
### Important note
|
||||||
|
|
||||||
|
- The kernel patches from [here](https://lore.kernel.org/platform-driver-x86/20240404001652.86207-1-luke@ljones.dev/) are required. The ppt settings _will_ still apply without the patches but will be called a fail due to the read-back not being implemented (solved with kernel patch). These patches have been upstreamed for kernel 6.10
|
||||||
|
- Z13 devices will need these Z13 devices will need [these](https://lore.kernel.org/linux-input/20240416090402.31057-1-luke@ljones.dev/T/#t)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Upgrade to zbus 4.0.1
|
||||||
|
- Switch UI over to slint
|
||||||
|
- Add ability to start rog-control-center fullscreen with a width and height. This should be useful for devices like the ROG Ally.
|
||||||
|
- Many small changes due to requirements of slint UI
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support GA402N keyboard
|
||||||
|
- Support GL553V keyboard
|
||||||
|
- Support GU605M keyboard
|
||||||
|
- Support Z13 lightbar (with kernel patch)
|
||||||
|
- Resupport the TUF keyboard
|
||||||
|
|
||||||
|
### BREAKING
|
||||||
|
|
||||||
|
- The aura dbus interface, and well pretty much all dbus interfaces have been changed. The Aura interface in particular works differently to begin implementing _multiple_ aura device support, including _hot-plug_ of devices (USB Aura keybords and others).
|
||||||
|
- All dbus interfaces except Aura are now in the `/org/asuslinux/` path
|
||||||
|
- Aura dbus now appear under `/org/asuslinux/<device>` and there may be multiple devices. To find these device you use the `ObjectManager` interface under the `/org/asuslinux` path.
|
||||||
|
|
||||||
|
## [v5.0.8]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Reintroduce persisting dark/light mode in config file
|
||||||
|
- Added ability to change what EPP is linked with each throttle profile
|
||||||
|
- Don't change EPP or thermal profile if the battery/ac state hasn't actually changed on resume
|
||||||
|
- Re-implement the `asusctl -s` command (not fully)
|
||||||
|
- Add more docs to some parts of code, and dbus interfaces
|
||||||
|
- Reload asusd.ron if changed. Does not notify any dbus listeners (yet)
|
||||||
|
- Fix the broken pipe error
|
||||||
|
- Remove the use of bytes in zbus signatures (another cause of broken pipe)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for G614J LED modes
|
||||||
|
|
||||||
|
## [v5.0.7]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix to suspend process in anime thread to let custom anims run on wake.
|
||||||
|
- Fix to reload the fan curves correctly on boot.
|
||||||
|
- Add new config option `platform_policy_linked_epp` to set if energy_performance_preference should be paired with platform_profile/throttle_thermal_policy
|
||||||
|
- Small fixes to rog-control-center
|
||||||
|
|
||||||
|
## [v5.0.6]
|
||||||
|
|
||||||
|
- Revert egui update due to a lot of issues arising from window closing.
|
||||||
|
|
||||||
|
## [v5.0.5]
|
||||||
|
|
||||||
|
- Resync. A release was made that was missing some commits.
|
||||||
|
|
||||||
|
## [v5.0.4]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Added G834JZ led config
|
||||||
|
- Fix in ROGCC to apply the actual effect changed
|
||||||
|
- Re-enable all fan curves (available) in ROGCC
|
||||||
|
- Update smithay-client-toolkit
|
||||||
|
|
||||||
|
## [v5.0.3]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix and error in platform ppt value gets
|
||||||
|
- Fix to asusctl CLI where an incorrect enum variant was used in throttle check
|
||||||
|
- Turn some error messages in to warning or info to prevent confusion
|
||||||
|
- Re-add the keyboard power settings in rogcc
|
||||||
|
- Add two new aura dbus properties for providing some basic info on aura modes/power
|
||||||
|
|
||||||
|
## [v5.0.2]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
- Fan-curves: nuke a few async deadlocks
|
- Fan-curves: nuke a few async deadlocks
|
||||||
- Anime: force power/wakeup disabled to prevent idiotic random wakes
|
- Anime: force power/wakeup disabled to prevent idiotic random wakes
|
||||||
|
|
||||||
## [v5.0.1]
|
## [v5.0.1]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix setting next fan profile
|
- Fix setting next fan profile
|
||||||
- Fix the assud.service
|
- Fix the assud.service
|
||||||
- Fix dbus signature of some power setting types for some keyboards
|
- Fix dbus signature of some power setting types for some keyboards
|
||||||
|
|
||||||
## [v5.0.0]
|
## [v5.0.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Gnome 45 plugin
|
- Gnome 45 plugin
|
||||||
- Support for G513RW LED modes
|
- Support for G513RW LED modes
|
||||||
- Support Rog Ally LED modes (basic)
|
- Support Rog Ally LED modes (basic)
|
||||||
@@ -29,10 +117,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- SetOffWhenLidClosed, also add asusctl CLI option
|
- SetOffWhenLidClosed, also add asusctl CLI option
|
||||||
- Anime: add brightness_on_battery config option
|
- Anime: add brightness_on_battery config option
|
||||||
- Platform: add `post_animation_sound`, kernel 6.7+ requires patch
|
- Platform: add `post_animation_sound`, kernel 6.7+ requires patch
|
||||||
- Add changing of CPU energy perfromance preference in relation to throttle_thermal_policy. This means that the CPU correctly behaves according to throttle_thermal_policy (and platform profile use is *removed*)
|
- Add changing of CPU energy perfromance preference in relation to throttle*thermal_policy. This means that the CPU correctly behaves according to throttle_thermal_policy (and platform profile use is \_removed*)
|
||||||
- Add setting of throttle_thermal_policy on power plug/unplug
|
- Add setting of throttle_thermal_policy on power plug/unplug
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- asusd: remove set_image_brightness for anime
|
- asusd: remove set_image_brightness for anime
|
||||||
- asusd: refactor how certain things like display enable/builtins are toggled
|
- asusd: refactor how certain things like display enable/builtins are toggled
|
||||||
- Refactor sleep/shutdown tasks
|
- Refactor sleep/shutdown tasks
|
||||||
@@ -45,18 +134,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Ensure builtin animations run instead of custom animations if option is set
|
- Ensure builtin animations run instead of custom animations if option is set
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|
||||||
- DBUS stuff. Again. All of it.
|
- DBUS stuff. Again. All of it.
|
||||||
|
|
||||||
## [v4.7.2]
|
## [v4.7.2]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for G733PZ LED modes
|
- Support for G733PZ LED modes
|
||||||
- Support for G713RC LED modes
|
- Support for G713RC LED modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix loading of fan curves from stored settings
|
- Fix loading of fan curves from stored settings
|
||||||
|
|
||||||
## [v4.7.1]
|
## [v4.7.1]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixes to asusctl CLI tool to show fan curves
|
- Fixes to asusctl CLI tool to show fan curves
|
||||||
- Fixes to asusd to ensure fan curve defaults are loaded if the config file fails
|
- Fixes to asusd to ensure fan curve defaults are loaded if the config file fails
|
||||||
- Further refine the asusctl CLI for fan-curve control
|
- Further refine the asusctl CLI for fan-curve control
|
||||||
@@ -64,10 +159,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Fixes to aura config creation/loading
|
- Fixes to aura config creation/loading
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for GV601V LED modes
|
- Support for GV601V LED modes
|
||||||
|
|
||||||
## [v4.7.0]
|
## [v4.7.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for FX507Z LED modes
|
- Support for FX507Z LED modes
|
||||||
- Support for GL503V LED modes
|
- Support for GL503V LED modes
|
||||||
- Support for G733C LED modes
|
- Support for G733C LED modes
|
||||||
@@ -90,10 +188,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add generation of introspection XML from asusd dbus
|
- Add generation of introspection XML from asusd dbus
|
||||||
- Add a reworked gnome extension to the main repo under `desktop-extensions/gnome/`. This was done to better keep the extension in sync with work done on asusd, especially around breaking dbus
|
- Add a reworked gnome extension to the main repo under `desktop-extensions/gnome/`. This was done to better keep the extension in sync with work done on asusd, especially around breaking dbus
|
||||||
- Add support for the mid fan custom curves on some laptops
|
- Add support for the mid fan custom curves on some laptops
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Move FX506HC to FX506H in arua DB to catch full series of this range
|
- Move FX506HC to FX506H in arua DB to catch full series of this range
|
||||||
- Move FX506LH to FX506L in arua DB to catch full series of this range
|
- Move FX506LH to FX506L in arua DB to catch full series of this range
|
||||||
- Move G513I* to G513I in arua DB to catch full series of this range
|
- Move G513I\* to G513I in arua DB to catch full series of this range
|
||||||
- Remove notification handle tracking limit, fixes KDE issue with profile notif
|
- Remove notification handle tracking limit, fixes KDE issue with profile notif
|
||||||
- Rename daemon and daemon-user crates to asusd and asusd-user to not be confusing in workspace naming
|
- Rename daemon and daemon-user crates to asusd and asusd-user to not be confusing in workspace naming
|
||||||
- Prevent the multiple notifications from a profile change from occuring (too many functions with side effects!)
|
- Prevent the multiple notifications from a profile change from occuring (too many functions with side effects!)
|
||||||
@@ -105,15 +205,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added button to fully quit app (exits from background)
|
- Added button to fully quit app (exits from background)
|
||||||
- Moved application settings to new page
|
- Moved application settings to new page
|
||||||
- Aura LED power refactor is now taken advantage of in RCC, exposing all settings
|
- Aura LED power refactor is now taken advantage of in RCC, exposing all settings
|
||||||
|
|
||||||
### BREAKING
|
### BREAKING
|
||||||
|
|
||||||
- All Anime related DBUS methods/notifs are changed
|
- All Anime related DBUS methods/notifs are changed
|
||||||
- All dbus interfaces that handled an enum have now been forced to use the enum as String type, not uint or similar, this unfortunately breaks a heap of stuff but has the benefit of allowing asusctl to use crates to generate a typescript (or other) binding to the types being used by zbus for the proxies. The implication here is that there will be an eventual tighter integration with the gnome extension and maybe KDE also.
|
- All dbus interfaces that handled an enum have now been forced to use the enum as String type, not uint or similar, this unfortunately breaks a heap of stuff but has the benefit of allowing asusctl to use crates to generate a typescript (or other) binding to the types being used by zbus for the proxies. The implication here is that there will be an eventual tighter integration with the gnome extension and maybe KDE also.
|
||||||
|
|
||||||
## [v4.6.2]
|
## [v4.6.2]
|
||||||
|
|
||||||
- Fix rog-control-center not reopening if `startup_in_background` is set
|
- Fix rog-control-center not reopening if `startup_in_background` is set
|
||||||
|
|
||||||
## [v4.6.1]
|
## [v4.6.1]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for G733Z LED modes
|
- Support for G733Z LED modes
|
||||||
- Support for GU604V LED modes
|
- Support for GU604V LED modes
|
||||||
- Support for GX650P LED modes
|
- Support for GX650P LED modes
|
||||||
@@ -123,7 +228,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Support for GV301VIC LED modes
|
- Support for GV301VIC LED modes
|
||||||
- Add device code for the plain Z13 keyboard (requires kernel patch, in progress)
|
- Add device code for the plain Z13 keyboard (requires kernel patch, in progress)
|
||||||
- Support for GV301V LED modes
|
- Support for GV301V LED modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Adjustments to Anime system events thread
|
- Adjustments to Anime system events thread
|
||||||
- Add "sleep" animetion config options to anime config
|
- Add "sleep" animetion config options to anime config
|
||||||
- rog-control-center dark/light mode persistency
|
- rog-control-center dark/light mode persistency
|
||||||
@@ -135,10 +242,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add support for Logout/Reboot in notification for KDE
|
- Add support for Logout/Reboot in notification for KDE
|
||||||
|
|
||||||
## [v4.6.0]
|
## [v4.6.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for GL703GE keyboard layout
|
- Support for GL703GE keyboard layout
|
||||||
- Support for G533Z modes and keyboard layout
|
- Support for G533Z modes and keyboard layout
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Better handling of `/etc/asusd` not existing
|
- Better handling of `/etc/asusd` not existing
|
||||||
- Better handling of non-existant config files
|
- Better handling of non-existant config files
|
||||||
- Move all config handling to generic traits for better consistency
|
- Move all config handling to generic traits for better consistency
|
||||||
@@ -149,64 +260,80 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- ROGCC: Don't notify user if changing to same mux mode
|
- ROGCC: Don't notify user if changing to same mux mode
|
||||||
- ROGCC: Add CLI opt for loading a keyboard layout for testing, with live-reload on file change
|
- ROGCC: Add CLI opt for loading a keyboard layout for testing, with live-reload on file change
|
||||||
- ROGCC: Add CLI opt for viewing all layout files + filenames to help find a layout matching your laptop
|
- ROGCC: Add CLI opt for viewing all layout files + filenames to help find a layout matching your laptop
|
||||||
+ Both of these options would hopefully be temporary and replaced with a "wizard" GUI helper
|
- Both of these options would hopefully be temporary and replaced with a "wizard" GUI helper
|
||||||
- Fix profile controller not detecting if platform_profile is changed
|
- Fix profile controller not detecting if platform_profile is changed
|
||||||
- Fix remove the leftover initial config writes on `new()` for some controllers to prevent resetting settings on startup
|
- Fix remove the leftover initial config writes on `new()` for some controllers to prevent resetting settings on startup
|
||||||
+ refactor the loading of systemd curve defaults and config file
|
- refactor the loading of systemd curve defaults and config file
|
||||||
|
|
||||||
### BREAKING
|
### BREAKING
|
||||||
|
|
||||||
- Rename aura dbus method from `per_key_raw` to `direct_addressing_raw` and add doc comment
|
- Rename aura dbus method from `per_key_raw` to `direct_addressing_raw` and add doc comment
|
||||||
- Changes to aura.conf:
|
- Changes to aura.conf:
|
||||||
- Changes to asusd-ledmodes.toml:
|
- Changes to asusd-ledmodes.toml:
|
||||||
+ Rename `standard` to `basic_modes`
|
- Rename `standard` to `basic_modes`
|
||||||
+ Rename `multizone` to `basic_zones`
|
- Rename `multizone` to `basic_zones`
|
||||||
+ Raname `per_key` to `advanced` and change type from `bool` to `AdvancedAuraType`
|
- Raname `per_key` to `advanced` and change type from `bool` to `AdvancedAuraType`
|
||||||
+ Removed `prod_family`
|
- Removed `prod_family`
|
||||||
+ Split all entries to `board_name` (separating `board_names`) (now a huge file)
|
- Split all entries to `board_name` (separating `board_names`) (now a huge file)
|
||||||
+ removed `asusd-ledmodes.toml` in favour of `aura_support.ron` due to an unsupported type in toml
|
- removed `asusd-ledmodes.toml` in favour of `aura_support.ron` due to an unsupported type in toml
|
||||||
- Rename and adjust `LedSupportedFunctions` to closely match the above
|
- Rename and adjust `LedSupportedFunctions` to closely match the above
|
||||||
|
|
||||||
## [v4.5.8]
|
## [v4.5.8]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix incorrect stop/start order of nvidia-powerd on AC plug/unplug
|
- Fix incorrect stop/start order of nvidia-powerd on AC plug/unplug
|
||||||
|
|
||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- ROGCC: Don't notify user if changing to same mux mode
|
- ROGCC: Don't notify user if changing to same mux mode
|
||||||
-
|
-
|
||||||
|
|
||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- ROGCC: Don't notify user if changing to same mux mode
|
- ROGCC: Don't notify user if changing to same mux mode
|
||||||
- asusd: don't block on systemd-unit change: removes all shoddy external command calls in favour of async dbus calls
|
- asusd: don't block on systemd-unit change: removes all shoddy external command calls in favour of async dbus calls
|
||||||
|
|
||||||
## [v4.5.6]
|
## [v4.5.6]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix tasks not always running correctly on boot/sleep/wake/shutdown by finishing the move to async
|
- Fix tasks not always running correctly on boot/sleep/wake/shutdown by finishing the move to async
|
||||||
- Change how the profile/fan change task monitors changes due to TUF laptops behaving slightly different
|
- Change how the profile/fan change task monitors changes due to TUF laptops behaving slightly different
|
||||||
- ROGCC: Better handle the use of GPU MUX without supergfxd
|
- ROGCC: Better handle the use of GPU MUX without supergfxd
|
||||||
- ROGCC: Track if reboot required when not using supergfxd
|
- ROGCC: Track if reboot required when not using supergfxd
|
||||||
- Add env var for logging levels to daemon and gui (`RUST_LOG=<error|warn|info|debug|trace>`)
|
- Add env var for logging levels to daemon and gui (`RUST_LOG=<error|warn|info|debug|trace>`)
|
||||||
- ROGCC: Very basic support for running a command on AC/Battery switching, this is in config at `~/.config/rog/rog-control-center.cfg`, and for now must be edited by hand and ROGCC restarted (run ROGCC in BG to use effectively)
|
- ROGCC: Very basic support for running a command on AC/Battery switching, this is in config at `~/.config/rog/rog-control-center.cfg`, and for now must be edited by hand and ROGCC restarted (run ROGCC in BG to use effectively)
|
||||||
+ Run ROGCC from terminal to see errors of the AC/Battery command
|
- Run ROGCC from terminal to see errors of the AC/Battery command
|
||||||
+ Support for editing via ROGCC GUI will come in future
|
- Support for editing via ROGCC GUI will come in future
|
||||||
+ This is ideal for userspace tasks
|
- This is ideal for userspace tasks
|
||||||
- asusd: Very basic support for running a command on AC/Battery switching, this is in config at `/etc/asusd/asusd.conf`. A restart of asusd is not required if edited.
|
- asusd: Very basic support for running a command on AC/Battery switching, this is in config at `/etc/asusd/asusd.conf`. A restart of asusd is not required if edited.
|
||||||
+ This is ideal for tasks that require root access (BE SAFE!)
|
- This is ideal for tasks that require root access (BE SAFE!)
|
||||||
- The above AC/Battery commands are probably best set to run a script for more complex tasks
|
- The above AC/Battery commands are probably best set to run a script for more complex tasks
|
||||||
- asusd: check if nvidia-powerd enabled before toggling
|
- asusd: check if nvidia-powerd enabled before toggling
|
||||||
|
|
||||||
## [v4.5.5]
|
## [v4.5.5]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- remove an unwrap() causing panic on main ROGCC thread
|
- remove an unwrap() causing panic on main ROGCC thread
|
||||||
|
|
||||||
## [v4.5.4]
|
## [v4.5.4]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- ROGCC:: Allow ROGCC to run without supergfxd
|
- ROGCC:: Allow ROGCC to run without supergfxd
|
||||||
- ROGCC: Tray/notifs now reads dGPU status directly via supergfx crate (supergfxd not required)
|
- ROGCC: Tray/notifs now reads dGPU status directly via supergfx crate (supergfxd not required)
|
||||||
- Add rust-toolchain to force minimum rust version
|
- Add rust-toolchain to force minimum rust version
|
||||||
|
|
||||||
## [v4.5.3]
|
## [v4.5.3]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Adjust how fan graph in ROGCC works, deny incorrect graphs
|
- Adjust how fan graph in ROGCC works, deny incorrect graphs
|
||||||
- Fix to apply the fan curve change in ROGCC to the correct profile
|
- Fix to apply the fan curve change in ROGCC to the correct profile
|
||||||
- Support for G713RS LED modes (Author: Peter Ivanov)
|
- Support for G713RS LED modes (Author: Peter Ivanov)
|
||||||
@@ -215,13 +342,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Update dependencies to get latest winit crate (fixes various small issues)
|
- Update dependencies to get latest winit crate (fixes various small issues)
|
||||||
|
|
||||||
## [v4.5.2]
|
## [v4.5.2]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Update dependencies and bump version
|
- Update dependencies and bump version
|
||||||
|
|
||||||
## [v4.5.1]
|
## [v4.5.1]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for FA506IE LED modes (Author: Herohtar)
|
- Support for FA506IE LED modes (Author: Herohtar)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add a basic system tray with dGPU status and gpu mode switch actions
|
- Add a basic system tray with dGPU status and gpu mode switch actions
|
||||||
- Fixup some notifications in ROGCC
|
- Fixup some notifications in ROGCC
|
||||||
- Add config options for notifications for ROGCC
|
- Add config options for notifications for ROGCC
|
||||||
@@ -229,7 +362,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Share tates with tray process in ROGCC
|
- Share tates with tray process in ROGCC
|
||||||
|
|
||||||
## [v4.5.0]
|
## [v4.5.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- intofy watches on:
|
- intofy watches on:
|
||||||
- `charge_control_end_threshold`
|
- `charge_control_end_threshold`
|
||||||
- `panel_od`
|
- `panel_od`
|
||||||
@@ -251,11 +386,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
problematic when on battery, not allowing the dgpu to suspend within decent time and
|
problematic when on battery, not allowing the dgpu to suspend within decent time and
|
||||||
sometimes blocking it completely.
|
sometimes blocking it completely.
|
||||||
- Notification to rog-control-center of dGPU state change
|
- Notification to rog-control-center of dGPU state change
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Use loops to ensure that mutex is gained for LED changes.
|
- Use loops to ensure that mutex is gained for LED changes.
|
||||||
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
||||||
- Properly fix notifs used in rog-control-center
|
- Properly fix notifs used in rog-control-center
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|
||||||
- DBUS: all charge control methods renamed to:
|
- DBUS: all charge control methods renamed to:
|
||||||
- `ChargeControlEndThreshold`
|
- `ChargeControlEndThreshold`
|
||||||
- `SetChargeControlEndThreshold`
|
- `SetChargeControlEndThreshold`
|
||||||
@@ -267,50 +406,66 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Path `/org/asuslinux/Charge` changed to `/org/asuslinux/Power`
|
- Path `/org/asuslinux/Charge` changed to `/org/asuslinux/Power`
|
||||||
|
|
||||||
## [v4.4.0] - 2022-08-29
|
## [v4.4.0] - 2022-08-29
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for per-key config has been added to `asusd-user`. At the moment it is
|
- Support for per-key config has been added to `asusd-user`. At the moment it is
|
||||||
basic with only a few effects done. Please see the manual for more information.
|
basic with only a few effects done. Please see the manual for more information.
|
||||||
- Support for unzoned and per-zone effects on some laptops. As above.
|
- Support for unzoned and per-zone effects on some laptops. As above.
|
||||||
- Added three effects to use with Zoned or Per-Key:
|
- Added three effects to use with Zoned or Per-Key:
|
||||||
+ Static, Breathe, Flicker. More to come.
|
- Static, Breathe, Flicker. More to come.
|
||||||
- Support for G713RS LED modes
|
- Support for G713RS LED modes
|
||||||
- Support for TUF laptop RGB (kernel patches required, these are submitted upstream)
|
- Support for TUF laptop RGB (kernel patches required, these are submitted upstream)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Create new rog-platform crate to manage all i/o in a universal way
|
- Create new rog-platform crate to manage all i/o in a universal way
|
||||||
+ kbd-led handling (requires kernel patches, TUF specific)
|
- kbd-led handling (requires kernel patches, TUF specific)
|
||||||
+ platform handling (asus-nb-wmi)
|
- platform handling (asus-nb-wmi)
|
||||||
+ power (basic, can be extended in future)
|
- power (basic, can be extended in future)
|
||||||
+ hidraw
|
- hidraw
|
||||||
+ usbraw
|
- usbraw
|
||||||
- Refactor how ROGCC handles IPC for background open, run-in-bg
|
- Refactor how ROGCC handles IPC for background open, run-in-bg
|
||||||
- Refactor daemon task creation to be simpler (for development)
|
- Refactor daemon task creation to be simpler (for development)
|
||||||
- Rename dpu_only to gpu_mux. Update all related messages and info.
|
- Rename dpu_only to gpu_mux. Update all related messages and info.
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|
||||||
- DBUS: rename path `/org/asuslinux/RogBios` to `/org/asuslinux/Platform`
|
- DBUS: rename path `/org/asuslinux/RogBios` to `/org/asuslinux/Platform`
|
||||||
- DBUS: renamed `dedicated_graphic_mode` to `gpu_mux_mode` (`GpuMuxMode`)
|
- DBUS: renamed `dedicated_graphic_mode` to `gpu_mux_mode` (`GpuMuxMode`)
|
||||||
- DBUS: renamed `set_dedicated_graphic_mode` to `set_gpu_mux_mode` (`SetGpuMuxMode`)
|
- DBUS: renamed `set_dedicated_graphic_mode` to `set_gpu_mux_mode` (`SetGpuMuxMode`)
|
||||||
+ The methods above take an enum: 0 = Discrete, 1 = Optimus
|
- The methods above take an enum: 0 = Discrete, 1 = Optimus
|
||||||
|
|
||||||
## [4.3.4] - 2022-08-03
|
## [4.3.4] - 2022-08-03
|
||||||
|
|
||||||
### Bugfix
|
### Bugfix
|
||||||
|
|
||||||
- ROGCC: Remove power setting from correct array
|
- ROGCC: Remove power setting from correct array
|
||||||
|
|
||||||
## [4.3.3] - 2022-08-02
|
## [4.3.3] - 2022-08-02
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `rog-control-center` has now been moved in to the main workspace due to
|
- `rog-control-center` has now been moved in to the main workspace due to
|
||||||
the heavy dependencies on most of the rog crates
|
the heavy dependencies on most of the rog crates
|
||||||
- Preliminary support of TUF RGB keyboards + power states
|
- Preliminary support of TUF RGB keyboards + power states
|
||||||
- Support for G713RW LED modes (Author: jarvis2709)
|
- Support for G713RW LED modes (Author: jarvis2709)
|
||||||
- Support for G713IC LED modes
|
- Support for G713IC LED modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- The udev rules have been changed to make asusd load with all gamer variants when asus-nb-wmi is loaded
|
- The udev rules have been changed to make asusd load with all gamer variants when asus-nb-wmi is loaded
|
||||||
- TUF, ROG, Zephyrus, Strix
|
- TUF, ROG, Zephyrus, Strix
|
||||||
|
|
||||||
## [4.3.0] - 2022-07-21
|
## [4.3.0] - 2022-07-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Clear command for anime `asusctl anime --clear` will clear the display
|
- Clear command for anime `asusctl anime --clear` will clear the display
|
||||||
- Re-added support for LED power states on `0x1866` type keyboards
|
- Re-added support for LED power states on `0x1866` type keyboards
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Make rog-anime more error tolerent. Remove various asserts and return errors instead
|
- Make rog-anime more error tolerent. Remove various asserts and return errors instead
|
||||||
- Return error if a pixel-gif is larger than the anime-display dimensions
|
- Return error if a pixel-gif is larger than the anime-display dimensions
|
||||||
- Both Anime and Aura dbus interfaces are changed a little
|
- Both Anime and Aura dbus interfaces are changed a little
|
||||||
@@ -319,45 +474,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- /org/asuslinux/Led renamed to /org/asuslinux/Aura
|
- /org/asuslinux/Led renamed to /org/asuslinux/Aura
|
||||||
|
|
||||||
## [4.2.1] - 2022-07-18
|
## [4.2.1] - 2022-07-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add panel overdrive support (autodetects if supported)
|
- Add panel overdrive support (autodetects if supported)
|
||||||
- Add detection of dgpu_disable and egpu_enable for diagnostic
|
- Add detection of dgpu_disable and egpu_enable for diagnostic
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixed save and restore of multizone LED settings
|
- Fixed save and restore of multizone LED settings
|
||||||
- Create defaults for multizone
|
- Create defaults for multizone
|
||||||
|
|
||||||
## [4.2.0] - 2022-07-16
|
## [4.2.0] - 2022-07-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for GA402 Anime Matrix display (Author: I-Al-Istannen & Luke Jones)
|
- Support for GA402 Anime Matrix display (Author: I-Al-Istannen & Luke Jones)
|
||||||
- Support for power-config of all LED zones. See `asusctrl led-power --help` (Author: Luke Jones, With much help from: @MNS26)
|
- Support for power-config of all LED zones. See `asusctrl led-power --help` (Author: Luke Jones, With much help from: @MNS26)
|
||||||
- Full support for multizone LED <logo, keyboard, lightbar> (Author: Luke Jones, With much help from: @MNS26)
|
- Full support for multizone LED <logo, keyboard, lightbar> (Author: Luke Jones, With much help from: @MNS26)
|
||||||
- Add ability to load extra data from `/etc/asusd/asusd-user-ledmodes.toml` for LED support if file exits
|
- Add ability to load extra data from `/etc/asusd/asusd-user-ledmodes.toml` for LED support if file exits
|
||||||
- Support for G513IM LED modes
|
- Support for G513IM LED modes
|
||||||
- Support for GX703HS LED modes
|
- Support for GX703HS LED modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Dbus interface for Aura config has been changed, all power control is done with `SetLedsEnabled` and `SetLedsDisabled`
|
- Dbus interface for Aura config has been changed, all power control is done with `SetLedsEnabled` and `SetLedsDisabled`
|
||||||
- Data for anime-matrix now requires passing the laptop model as enum
|
- Data for anime-matrix now requires passing the laptop model as enum
|
||||||
- Extra unit tests for anime stuff to help verify things
|
- Extra unit tests for anime stuff to help verify things
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for GA503R LED modes
|
- Support for GA503R LED modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Refactor LED and AniMe tasks
|
- Refactor LED and AniMe tasks
|
||||||
- Reload keyboard brightness on resume from sleep/hiber
|
- Reload keyboard brightness on resume from sleep/hiber
|
||||||
|
|
||||||
## [4.1.1] - 2022-06-21
|
## [4.1.1] - 2022-06-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixes to anime matrix system thread cancelation
|
- Fixes to anime matrix system thread cancelation
|
||||||
|
|
||||||
## [4.1.0] - 2022-06-20
|
## [4.1.0] - 2022-06-20
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Huge refactor to use zbus 2.2 + zvariant 3.0 in system-daemon.
|
- Huge refactor to use zbus 2.2 + zvariant 3.0 in system-daemon.
|
||||||
- Daemons with tasks now use `smol` for async ops.
|
- Daemons with tasks now use `smol` for async ops.
|
||||||
- Fixes to fan-curve settings from CLI (Author: Armas Span)
|
- Fixes to fan-curve settings from CLI (Author: Armas Span)
|
||||||
- Add brightness to anime zbus notification
|
- Add brightness to anime zbus notification
|
||||||
- Adjust how threads in AniMe matrix controller work
|
- Adjust how threads in AniMe matrix controller work
|
||||||
- Use proper power-state packet for keyboard LED's (Author: Martin Piffault)
|
- Use proper power-state packet for keyboard LED's (Author: Martin Piffault)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for GA402R LED modes
|
- Support for GA402R LED modes
|
||||||
- Support for GU502LV LED modes
|
- Support for GU502LV LED modes
|
||||||
- Support for G512 LED modes
|
- Support for G512 LED modes
|
||||||
@@ -369,27 +541,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Support running AniMe animation blocks on wake/sleep and boot/shutdown events
|
- Support running AniMe animation blocks on wake/sleep and boot/shutdown events
|
||||||
|
|
||||||
# [4.0.7] - 2021-12-19
|
# [4.0.7] - 2021-12-19
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix incorrect power-profile validation
|
- Fix incorrect power-profile validation
|
||||||
- Update asusd-ledmodes.toml to support Asus Rog Strix G15 G513QE (@LordVicky)
|
- Update asusd-ledmodes.toml to support Asus Rog Strix G15 G513QE (@LordVicky)
|
||||||
- Update patch notes and links
|
- Update patch notes and links
|
||||||
|
|
||||||
# [4.0.6] - 2021-11-01
|
# [4.0.6] - 2021-11-01
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix CLI for bios toggles
|
- Fix CLI for bios toggles
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Extra commands for AniMe: pixel-image, gif, pixel-gif
|
- Extra commands for AniMe: pixel-image, gif, pixel-gif
|
||||||
|
|
||||||
# [4.0.5] - 2021-10-27
|
# [4.0.5] - 2021-10-27
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Convert fan curve percentage to 0-255 expected by kernel driver only if '%' char is used, otherwise the expected range for fan power is 0-255
|
- Convert fan curve percentage to 0-255 expected by kernel driver only if '%' char is used, otherwise the expected range for fan power is 0-255
|
||||||
- Use correct error in daemon for invalid charging limit
|
- Use correct error in daemon for invalid charging limit
|
||||||
- Enforce charging limit values in range 20-100
|
- Enforce charging limit values in range 20-100
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- LED modes for G513QR
|
- LED modes for G513QR
|
||||||
|
|
||||||
# [4.0.4] - 2021-10-02
|
# [4.0.4] - 2021-10-02
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add missing Profile commands
|
- Add missing Profile commands
|
||||||
- Spawn tasks on individual threads to prevent blocking
|
- Spawn tasks on individual threads to prevent blocking
|
||||||
- Don't force fan-curve default on reload
|
- Don't force fan-curve default on reload
|
||||||
@@ -397,83 +581,107 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Slim down the notification daemon to pure ASUS notifications
|
- Slim down the notification daemon to pure ASUS notifications
|
||||||
|
|
||||||
# [4.0.3] - 2021-09-16
|
# [4.0.3] - 2021-09-16
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Don't show fan-curve warning if fan-curve available
|
- Don't show fan-curve warning if fan-curve available
|
||||||
- Add G713QR to Strix led-modes
|
- Add G713QR to Strix led-modes
|
||||||
- Fix part of CLI fan-curve control
|
- Fix part of CLI fan-curve control
|
||||||
|
|
||||||
# [4.0.2] - 2021-09-14
|
# [4.0.2] - 2021-09-14
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Backup old configs to *-old if parse fails
|
|
||||||
|
- Backup old configs to \*-old if parse fails
|
||||||
- Prevent some types of crashes related to unpatched kernels
|
- Prevent some types of crashes related to unpatched kernels
|
||||||
- Add better help for graphics errors
|
- Add better help for graphics errors
|
||||||
- Add better help for asusctl general errors
|
- Add better help for asusctl general errors
|
||||||
- Implement fan-curve dbus API
|
- Implement fan-curve dbus API
|
||||||
- Implement partial fan-curve control via CLI tool
|
- Implement partial fan-curve control via CLI tool
|
||||||
+ Set fan curve for profile + fan gpu/cpu
|
- Set fan curve for profile + fan gpu/cpu
|
||||||
|
|
||||||
# [4.0.1] - 2021-09-11
|
# [4.0.1] - 2021-09-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix asusd-ledmodes.toml
|
- Fix asusd-ledmodes.toml
|
||||||
|
|
||||||
# [4.0.0] - 2021-09-10
|
# [4.0.0] - 2021-09-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- AniMe:
|
- AniMe:
|
||||||
+ Support 8bit RGB, RGBA, 16bit Greyscalw, RGB, RGBA
|
- Support 8bit RGB, RGBA, 16bit Greyscalw, RGB, RGBA
|
||||||
+ add `AsusImage` type for slanted-template pixel-perfect images
|
- add `AsusImage` type for slanted-template pixel-perfect images
|
||||||
+ `BREAKING:` plain `Image` with time period is changed and old anime configs break as a result (sorry)
|
- `BREAKING:` plain `Image` with time period is changed and old anime configs break as a result (sorry)
|
||||||
- LED:
|
- LED:
|
||||||
+ By popular request LED prev/next cycle is added
|
- By popular request LED prev/next cycle is added
|
||||||
+ Add led modes for GX551Q
|
- Add led modes for GX551Q
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
- Graphics control:
|
- Graphics control:
|
||||||
+ graphics control is pulled out of asusd and moved to new package; https://gitlab.com/asus-linux/supergfxctl
|
- graphics control is pulled out of asusd and moved to new package; https://gitlab.com/asus-linux/supergfxctl
|
||||||
- Proflies:
|
- Proflies:
|
||||||
+ profiles now depend on power-profile-daemon plus kernel patches for support of platform_profile
|
- profiles now depend on power-profile-daemon plus kernel patches for support of platform_profile
|
||||||
- if your system supports fan-curves you will also require upcoming kernel patches for this
|
- if your system supports fan-curves you will also require upcoming kernel patches for this
|
||||||
+ profiles are now moved to a new file
|
- profiles are now moved to a new file
|
||||||
+ fan-curves are only partially completed due to this release needing to be done sooner
|
- fan-curves are only partially completed due to this release needing to be done sooner
|
||||||
|
|
||||||
# [3.7.2] - 2021-08-02
|
# [3.7.2] - 2021-08-02
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Enable multizone support on Strix 513IH
|
- Enable multizone support on Strix 513IH
|
||||||
- Add G513QY ledmodes
|
- Add G513QY ledmodes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix missing CLI command help for some supported options
|
- Fix missing CLI command help for some supported options
|
||||||
- Fix incorrectly selecting profile by name, where the active profile was being copied to the selected profile
|
- Fix incorrectly selecting profile by name, where the active profile was being copied to the selected profile
|
||||||
- Add `asusd` version back to `asusctl -v` report
|
- Add `asusd` version back to `asusctl -v` report
|
||||||
- Fix various clippy warnings
|
- Fix various clippy warnings
|
||||||
|
|
||||||
# [3.7.1] - 2021-06-11
|
# [3.7.1] - 2021-06-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Refine graphics mode switching:
|
- Refine graphics mode switching:
|
||||||
+ Disallow switching to compute or vfio mode unless existing mode is "Integrated"
|
- Disallow switching to compute or vfio mode unless existing mode is "Integrated"
|
||||||
|
|
||||||
# [3.7.0] - 2021-06-06
|
# [3.7.0] - 2021-06-06
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Set PM to auto for Nvidia always
|
- Set PM to auto for Nvidia always
|
||||||
- Extra info output for gfx dev scan
|
- Extra info output for gfx dev scan
|
||||||
- Extra info in log for G-Sync to help prevent user confusion around gfx switching
|
- Extra info in log for G-Sync to help prevent user confusion around gfx switching
|
||||||
- Add GA503Q led modes
|
- Add GA503Q led modes
|
||||||
- Added ability to fade in/out gifs and images for anime. This does break anime configs. See manual for details.
|
- Added ability to fade in/out gifs and images for anime. This does break anime configs. See manual for details.
|
||||||
- Added task to CtrlLed to set the keyboard LED brightness on wake from suspend
|
- Added task to CtrlLed to set the keyboard LED brightness on wake from suspend
|
||||||
+ requires a kernel patch which will be upstreamed and in fedora rog kernel
|
- requires a kernel patch which will be upstreamed and in fedora rog kernel
|
||||||
- Make gfx change from nvidia to vfio/compute also force-change to integrated _then_
|
- Make gfx change from nvidia to vfio/compute also force-change to integrated _then_
|
||||||
to requested mode
|
to requested mode
|
||||||
- Fix invalid gfx status when switching from some modes
|
- Fix invalid gfx status when switching from some modes
|
||||||
- Fix copy over of serde skipped config values on config reload
|
- Fix copy over of serde skipped config values on config reload
|
||||||
|
|
||||||
# [3.6.1] - 2021-05-25
|
# [3.6.1] - 2021-05-25
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfix: write correct fan modes for profiles
|
- Bugfix: write correct fan modes for profiles
|
||||||
- Bugfix: apply created profiles
|
- Bugfix: apply created profiles
|
||||||
|
|
||||||
# [3.6.1] - 2021-05-25
|
# [3.6.1] - 2021-05-25
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfix for cycling through profiles
|
- Bugfix for cycling through profiles
|
||||||
|
|
||||||
# [3.6.0] - 2021-05-24
|
# [3.6.0] - 2021-05-24
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add GX550L led modes
|
- Add GX550L led modes
|
||||||
- Don't save compute/vfio modes. Option in config for this is removed.
|
- Don't save compute/vfio modes. Option in config for this is removed.
|
||||||
- Store a temporary non-serialised option in config for if compute/vfio is active
|
- Store a temporary non-serialised option in config for if compute/vfio is active
|
||||||
@@ -488,49 +696,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Fix some dbus Supported issues
|
- Fix some dbus Supported issues
|
||||||
|
|
||||||
# [3.5.2] - 2021-05-15
|
# [3.5.2] - 2021-05-15
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfix: prevent the hang on compute/integrated mode change
|
- Bugfix: prevent the hang on compute/integrated mode change
|
||||||
|
|
||||||
# [3.5.1] - 2021-04-25
|
# [3.5.1] - 2021-04-25
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
+ Anime:
|
|
||||||
|
- Anime:
|
||||||
- Fix using multiple configs
|
- Fix using multiple configs
|
||||||
|
|
||||||
# [3.5.0] - 2021-04-25
|
# [3.5.0] - 2021-04-25
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
+ Keyboard:
|
|
||||||
|
- Keyboard:
|
||||||
- Split out all aura functionality that isn't dependent on the daemon in to a
|
- Split out all aura functionality that isn't dependent on the daemon in to a
|
||||||
new crate `rog-aura` (incomplete)
|
new crate `rog-aura` (incomplete)
|
||||||
- Keyboard LED control now includes:
|
- Keyboard LED control now includes:
|
||||||
+ Enable/disable LED's while laptop is awake
|
- Enable/disable LED's while laptop is awake
|
||||||
+ Enable/disable LED animation while laptop is suspended and AC plugged in
|
- Enable/disable LED animation while laptop is suspended and AC plugged in
|
||||||
- Properly reload the last used keyboard mode on boot
|
- Properly reload the last used keyboard mode on boot
|
||||||
+ Graphics:
|
- Graphics:
|
||||||
- Correctly enable compute mode for nvidia plus no-reboot or logout if switching
|
- Correctly enable compute mode for nvidia plus no-reboot or logout if switching
|
||||||
from vfio/integrated/compute.
|
from vfio/integrated/compute.
|
||||||
- Add asusd config option to not save compute/vfio mode switch.
|
- Add asusd config option to not save compute/vfio mode switch.
|
||||||
+ Anime:
|
- Anime:
|
||||||
- Enable basic multiple user anime configs (asusd-user must still be restarted)
|
- Enable basic multiple user anime configs (asusd-user must still be restarted)
|
||||||
+ Profiles:
|
- Profiles:
|
||||||
- Enable dbus methods for freq min/max, fan curve, fan preset, CPU turbo enable.
|
- Enable dbus methods for freq min/max, fan curve, fan preset, CPU turbo enable.
|
||||||
These options will apply to the active profile if no profile name is specified.
|
These options will apply to the active profile if no profile name is specified.
|
||||||
|
|
||||||
# [3.4.1] - 2021-04-11
|
# [3.4.1] - 2021-04-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix anime init sequence
|
- Fix anime init sequence
|
||||||
|
|
||||||
# [3.4.0] - 2021-04-11
|
# [3.4.0] - 2021-04-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Revert zbus to 1.9.1
|
- Revert zbus to 1.9.1
|
||||||
- Use enum to show power states, and catch missing pci path for nvidia.
|
- Use enum to show power states, and catch missing pci path for nvidia.
|
||||||
- Partial user-daemon for anime/per-key done, `asusd-user`. Includes asusd-user systemd unit.
|
- Partial user-daemon for anime/per-key done, `asusd-user`. Includes asusd-user systemd unit.
|
||||||
- user-daemon provides dbus emthods to insert anime actions, remove from index, set leds on/off
|
- user-daemon provides dbus emthods to insert anime actions, remove from index, set leds on/off
|
||||||
+ Config file is stored in `~/.config/rog/rog-user.cfg`
|
- Config file is stored in `~/.config/rog/rog-user.cfg`
|
||||||
- AniMe display parts split out to individual crate in preparation for publishing
|
- AniMe display parts split out to individual crate in preparation for publishing
|
||||||
on crates.io
|
on crates.io
|
||||||
|
|
||||||
# [3.3.0] - 2021-04-3
|
# [3.3.0] - 2021-04-3
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add ledmodes for G733QS
|
- Add ledmodes for G733QS
|
||||||
- Add ledmodes for GA401Q
|
- Add ledmodes for GA401Q
|
||||||
- Default to vfio disabled in configuration. Will now hard-error if enabled and
|
- Default to vfio disabled in configuration. Will now hard-error if enabled and
|
||||||
@@ -538,91 +758,126 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
must be changed to `true` in `/etc/asusd/asusd.conf`
|
must be changed to `true` in `/etc/asusd/asusd.conf`
|
||||||
|
|
||||||
# [3.2.4] - 2021-03-24
|
# [3.2.4] - 2021-03-24
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Ignore vfio-builtin error if switching to integrated
|
- Ignore vfio-builtin error if switching to integrated
|
||||||
|
|
||||||
# [3.2.3] - 2021-03-24
|
# [3.2.3] - 2021-03-24
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Better handling of session tracking
|
- Better handling of session tracking
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- List all profile data
|
- List all profile data
|
||||||
- Get active profile name
|
- Get active profile name
|
||||||
- Get active profile data
|
- Get active profile data
|
||||||
|
|
||||||
# [3.2.2] - 2021-03-23
|
# [3.2.2] - 2021-03-23
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix brightness control, again, for non-RGB keyboards
|
- Fix brightness control, again, for non-RGB keyboards
|
||||||
|
|
||||||
# [3.2.1] - 2021-03-21
|
# [3.2.1] - 2021-03-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix brightness control
|
- Fix brightness control
|
||||||
- Large cleanup of code relating to LED controls
|
- Large cleanup of code relating to LED controls
|
||||||
|
|
||||||
# [3.2.0] - 2021-03-21
|
# [3.2.0] - 2021-03-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Refactor keyboard LED handling
|
- Refactor keyboard LED handling
|
||||||
- Added --list for profiles (Thanks @aqez)
|
- Added --list for profiles (Thanks @aqez)
|
||||||
- Added --remove for profiles (Thanks @aqez)
|
- Added --remove for profiles (Thanks @aqez)
|
||||||
- Added a graphics mode: vfio. This attaches Nvidia devices to vfio module.
|
- Added a graphics mode: vfio. This attaches Nvidia devices to vfio module.
|
||||||
|
|
||||||
### Broken
|
### Broken
|
||||||
|
|
||||||
- Per-key LED modes, which need thinking about how to go ahead with for future
|
- Per-key LED modes, which need thinking about how to go ahead with for future
|
||||||
|
|
||||||
# [3.1.7] - 2021-03-11
|
# [3.1.7] - 2021-03-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Refactor many parts of daemon
|
- Refactor many parts of daemon
|
||||||
- Switch out session monitoring to logind-zbus
|
- Switch out session monitoring to logind-zbus
|
||||||
|
|
||||||
# [3.1.6] - 2021-03-11
|
# [3.1.6] - 2021-03-11
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Graphics switching will now wait until all users logged out before switching
|
- Graphics switching will now wait until all users logged out before switching
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Further tweaks to gfx switching
|
- Further tweaks to gfx switching
|
||||||
- More logging on gfx switching
|
- More logging on gfx switching
|
||||||
- Filter bios help according to supported modes
|
- Filter bios help according to supported modes
|
||||||
- Prevent gfx mode switching if in dedicated/G-Sync mode
|
- Prevent gfx mode switching if in dedicated/G-Sync mode
|
||||||
|
|
||||||
# [3.1.4] - 2021-03-10
|
# [3.1.4] - 2021-03-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Notify through dbus if user changes profile manually
|
- Notify through dbus if user changes profile manually
|
||||||
- Better help on CLI, show help only for supported items
|
- Better help on CLI, show help only for supported items
|
||||||
- Bugfix to gfx switcher
|
- Bugfix to gfx switcher
|
||||||
|
|
||||||
# [3.1.3] - 2021-03-10
|
# [3.1.3] - 2021-03-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Hotfix: gracefully handle removing modules in use caused by display-manager not
|
- Hotfix: gracefully handle removing modules in use caused by display-manager not
|
||||||
fully shutdown at the time of trying to remove modules. It will now retry every
|
fully shutdown at the time of trying to remove modules. It will now retry every
|
||||||
250ms per module
|
250ms per module
|
||||||
|
|
||||||
# [3.1.2] - 2021-03-10
|
# [3.1.2] - 2021-03-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Test and create /etc/X11/xorg.conf.d/ if it doesn't exist
|
- Test and create /etc/X11/xorg.conf.d/ if it doesn't exist
|
||||||
- Hotfix to better report module issues
|
- Hotfix to better report module issues
|
||||||
|
|
||||||
# [3.1.1] - 2021-03-10
|
# [3.1.1] - 2021-03-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add missing nvidia module nvidia_uvm to gfx ctrl list
|
- Add missing nvidia module nvidia_uvm to gfx ctrl list
|
||||||
|
|
||||||
# [3.1.0] - 2021-03-09
|
# [3.1.0] - 2021-03-09
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- GU502LU led-modes
|
- GU502LU led-modes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Graphics switching is now rebootless, the daemon will now restart the
|
- Graphics switching is now rebootless, the daemon will now restart the
|
||||||
display-manager to switch modes instead. Caveats are:
|
display-manager to switch modes instead. Caveats are:
|
||||||
+ There is no confirmation from the daemon, the program issuing the command
|
- There is no confirmation from the daemon, the program issuing the command
|
||||||
must confirm the request.
|
must confirm the request.
|
||||||
+ systemd only
|
- systemd only
|
||||||
- Laptops with dedicated Nvidia mode:
|
- Laptops with dedicated Nvidia mode:
|
||||||
+ You still must reboot for the bios to switch modes
|
- You still must reboot for the bios to switch modes
|
||||||
+ On boot if dedicated mode is active then asusd will update the required configs
|
- On boot if dedicated mode is active then asusd will update the required configs
|
||||||
to put display-manager in nvidia mode
|
to put display-manager in nvidia mode
|
||||||
|
|
||||||
# [3.0.0] - 2021-02-22
|
# [3.0.0] - 2021-02-22
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- G531GD led modes
|
- G531GD led modes
|
||||||
|
|
||||||
# [3.0.0] - 2021-02-14
|
# [3.0.0] - 2021-02-14
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Write set+apply after each array in multizone
|
- Write set+apply after each array in multizone
|
||||||
- Remove misc bad logic
|
- Remove misc bad logic
|
||||||
- Use same code path as 0x1866 device to configure led support for 0x1854 device
|
- Use same code path as 0x1866 device to configure led support for 0x1854 device
|
||||||
@@ -634,14 +889,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Cleanup fan and cpu control + configs
|
- Cleanup fan and cpu control + configs
|
||||||
|
|
||||||
# [2.2.2] - 2021-01-31
|
# [2.2.2] - 2021-01-31
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix for dedicated gfx capable laptops in integrated mode
|
- Fix for dedicated gfx capable laptops in integrated mode
|
||||||
- Fix for 0x1854 device
|
- Fix for 0x1854 device
|
||||||
|
|
||||||
# [2.2.1] - 2021-01-27
|
# [2.2.1] - 2021-01-27
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add ROG Zephyrus M15 LED config
|
- Add ROG Zephyrus M15 LED config
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfixes
|
- Bugfixes
|
||||||
- Fix reboot/restartx status for GFX switching
|
- Fix reboot/restartx status for GFX switching
|
||||||
- Update readme
|
- Update readme
|
||||||
@@ -649,29 +910,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Make dracut include the nvidia modules in initramfs
|
- Make dracut include the nvidia modules in initramfs
|
||||||
|
|
||||||
# [2.2.0] - 2021-01-26
|
# [2.2.0] - 2021-01-26
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Dbus command to fetch all supported functions of the laptop. That is, all the
|
- Dbus command to fetch all supported functions of the laptop. That is, all the
|
||||||
functions that asusd supports for the currently running laptop.
|
functions that asusd supports for the currently running laptop.
|
||||||
- Bios setting toggles for:
|
- Bios setting toggles for:
|
||||||
+ Dedicated gfx toggle (support depends on the laptop)
|
- Dedicated gfx toggle (support depends on the laptop)
|
||||||
+ Bios boot POST sound toggle
|
- Bios boot POST sound toggle
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- added config option for dedicated gfx mode on laptops with it to enable
|
- added config option for dedicated gfx mode on laptops with it to enable
|
||||||
switching directly to dedicated using `asusctl graphics -m nvidia`
|
switching directly to dedicated using `asusctl graphics -m nvidia`
|
||||||
|
|
||||||
# [2.1.2] - 2021-01-10
|
# [2.1.2] - 2021-01-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Adjust gfx controller to assume that the graphics driver is loaded if the
|
- Adjust gfx controller to assume that the graphics driver is loaded if the
|
||||||
mode is set for nvidia/hybrid
|
mode is set for nvidia/hybrid
|
||||||
|
|
||||||
# [2.1.1] - 2021-01-09
|
# [2.1.1] - 2021-01-09
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Updates to dependencies
|
- Updates to dependencies
|
||||||
|
|
||||||
# [2.1.0] - 2020-10-25
|
# [2.1.0] - 2020-10-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Option to turn off AniMe display (@asere)
|
- Option to turn off AniMe display (@asere)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Change option -k to show current LED bright (@asere)
|
- Change option -k to show current LED bright (@asere)
|
||||||
- Correctly disable GFX control via config
|
- Correctly disable GFX control via config
|
||||||
- Panic and exit if config can't be parsed
|
- Panic and exit if config can't be parsed
|
||||||
@@ -679,57 +952,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add DBUS method to toggle to next/prev Aura mode
|
- Add DBUS method to toggle to next/prev Aura mode
|
||||||
|
|
||||||
# [2.0.5] - 2020-09-29
|
# [2.0.5] - 2020-09-29
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfixes
|
- Bugfixes
|
||||||
|
|
||||||
# [2.0.4] - 2020-09-24
|
# [2.0.4] - 2020-09-24
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Better and more verbose error handling and logging in many places.
|
- Better and more verbose error handling and logging in many places.
|
||||||
- Fix timeout for client waiting on reply for graphics switching
|
- Fix timeout for client waiting on reply for graphics switching
|
||||||
|
|
||||||
# [2.0.2] - 2020-09-21
|
# [2.0.2] - 2020-09-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- graphics options via CLI are now a command block:
|
- graphics options via CLI are now a command block:
|
||||||
+ `asusctl graphics`
|
- `asusctl graphics`
|
||||||
+ -m Mode <nvidia, hybrid, compute, integrated>
|
- -m Mode <nvidia, hybrid, compute, integrated>
|
||||||
+ -g Get current mode
|
- -g Get current mode
|
||||||
+ -f Force reboot or restart display manager without confirmation
|
- -f Force reboot or restart display manager without confirmation
|
||||||
|
|
||||||
# [2.0.0] - 2020-09-21
|
# [2.0.0] - 2020-09-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Code refactor to spawn less tasks. Main loop will run only as fast as
|
- Code refactor to spawn less tasks. Main loop will run only as fast as
|
||||||
it receives events
|
it receives events
|
||||||
- No-longer using tokio or async, reducing resource use
|
- No-longer using tokio or async, reducing resource use
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- A basic user daemon has been added for user notifications over dbus (XDG spec)
|
- A basic user daemon has been added for user notifications over dbus (XDG spec)
|
||||||
- Added a user systemd service for notifications (asus-notify)
|
- Added a user systemd service for notifications (asus-notify)
|
||||||
- Graphics mode handling <iGPU only, dGPU only, or hybrid>, see asusctl --help
|
- Graphics mode handling <iGPU only, dGPU only, or hybrid>, see asusctl --help
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
- asusd.conf has changed slightly and will overwrite old configs
|
- asusd.conf has changed slightly and will overwrite old configs
|
||||||
- All DBUS methods/signals/paths etc, are all updated and changed
|
- All DBUS methods/signals/paths etc, are all updated and changed
|
||||||
|
|
||||||
# [1.1.2] - 2020-09-10
|
# [1.1.2] - 2020-09-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bump rog-fan-curve to new versiont o support GA401IV
|
- Bump rog-fan-curve to new versiont o support GA401IV
|
||||||
|
|
||||||
# [1.1.1] - 2020-09-10
|
# [1.1.1] - 2020-09-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Correction to AMD turbo setting
|
- Correction to AMD turbo setting
|
||||||
|
|
||||||
# [1.1.0] - 2020-09-10
|
# [1.1.0] - 2020-09-10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Uses string instead of debug print for some errors
|
- Uses string instead of debug print for some errors
|
||||||
- Add interface num arg for LED controller (should help support
|
- Add interface num arg for LED controller (should help support
|
||||||
older laptops better)
|
older laptops better)
|
||||||
- Some slightly better error messages
|
- Some slightly better error messages
|
||||||
- Fix an idiotic mistake in `for i in 0..2.. if i > 0` -_-
|
- Fix an idiotic mistake in `for i in 0..2.. if i > 0` -\_-
|
||||||
- Remove "unsupported" warning on laptop ctrl
|
- Remove "unsupported" warning on laptop ctrl
|
||||||
- Silence warning about AniMe not existing
|
- Silence warning about AniMe not existing
|
||||||
- Adjust the turbo-toggle CLI arg
|
- Adjust the turbo-toggle CLI arg
|
||||||
- Version bump for new release with fancurves
|
- Version bump for new release with fancurves
|
||||||
|
|
||||||
## [1.0.2] - 2020-08-13
|
## [1.0.2] - 2020-08-13
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bugfixes to led brightness watcher
|
- Bugfixes to led brightness watcher
|
||||||
- Bufixes to await/async tasks
|
- Bufixes to await/async tasks
|
||||||
|
|
||||||
|
|||||||
Generated
+2711
-1276
File diff suppressed because it is too large
Load Diff
+41
-12
@@ -1,20 +1,47 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["asusctl", "asusd", "asusd-user", "config-traits", "cpuctl", "dmi-id", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
|
members = [
|
||||||
default-members = ["asusctl", "asusd", "asusd-user", "cpuctl", "rog-control-center"]
|
"asusctl",
|
||||||
|
"asusd",
|
||||||
|
"asusd-user",
|
||||||
|
"config-traits",
|
||||||
|
"cpuctl",
|
||||||
|
"dmi-id",
|
||||||
|
"rog-platform",
|
||||||
|
"rog-dbus",
|
||||||
|
"rog-anime",
|
||||||
|
"rog-aura",
|
||||||
|
"rog-profiles",
|
||||||
|
"rog-control-center",
|
||||||
|
"rog-slash",
|
||||||
|
"simulators",
|
||||||
|
]
|
||||||
|
default-members = [
|
||||||
|
"asusctl",
|
||||||
|
"asusd",
|
||||||
|
"asusd-user",
|
||||||
|
"cpuctl",
|
||||||
|
"rog-control-center",
|
||||||
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "5.0.2"
|
version = "6.0.0"
|
||||||
|
rust-version = "1.77"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "^0.1"
|
tokio = { version = "^1.36.0", default-features = false, features = [
|
||||||
tokio = { version = "^1.23.0", default-features = false, features = ["macros", "sync"]}
|
"macros",
|
||||||
|
"sync",
|
||||||
|
"time",
|
||||||
|
"rt-multi-thread",
|
||||||
|
] }
|
||||||
concat-idents = "^1.1"
|
concat-idents = "^1.1"
|
||||||
dirs = "^4.0"
|
dirs = "^4.0"
|
||||||
smol = "^1.3"
|
smol = "^1.3"
|
||||||
|
mio = "0.8.11"
|
||||||
|
|
||||||
zbus = "~3.14.1"
|
zbus = "~4.1.2"
|
||||||
logind-zbus = { version = "~3.1" } #, default-features = false, features = ["non_blocking"] }
|
logind-zbus = { version = "~4.0.2" } #, default-features = false, features = ["non_blocking"] }
|
||||||
|
|
||||||
serde = "^1.0"
|
serde = "^1.0"
|
||||||
serde_derive = "^1.0"
|
serde_derive = "^1.0"
|
||||||
@@ -28,7 +55,7 @@ env_logger = "^0.10.0"
|
|||||||
|
|
||||||
glam = { version = "^0.22", features = ["serde"] }
|
glam = { version = "^0.22", features = ["serde"] }
|
||||||
gumdrop = "^0.8"
|
gumdrop = "^0.8"
|
||||||
udev = "^0.7"
|
udev = { version = "^0.8", features = ["mio"] }
|
||||||
rusb = "^0.9"
|
rusb = "^0.9"
|
||||||
inotify = "^0.10.0"
|
inotify = "^0.10.0"
|
||||||
|
|
||||||
@@ -39,7 +66,9 @@ gif = "^0.12.0"
|
|||||||
|
|
||||||
versions = "4.1"
|
versions = "4.1"
|
||||||
|
|
||||||
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-features = false, features = ["z"] }
|
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", rev = "54176413b81189a3e4edbdc20a0b4f7e2e35c063", default-features = false, features = [
|
||||||
|
"z",
|
||||||
|
] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
# thin = 57s, asusd = 9.0M
|
# thin = 57s, asusd = 9.0M
|
||||||
@@ -48,11 +77,11 @@ lto = "fat"
|
|||||||
debug = false
|
debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
#codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = true
|
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
codegen-units = 16
|
||||||
|
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
debug = false
|
debug = false
|
||||||
@@ -61,4 +90,4 @@ opt-level = 3
|
|||||||
[workspace.dependencies.cargo-husky]
|
[workspace.dependencies.cargo-husky]
|
||||||
version = "1"
|
version = "1"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["user-hooks"]
|
features = ["user-hooks"]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# asusctrl manual
|
# asusctrl manual
|
||||||
|
|
||||||
|
**NOTE:** this manual is in need of an update in some places. If you find issues please file issue reports.
|
||||||
|
|
||||||
`asusd` is a utility for Linux to control many aspects of various ASUS laptops
|
`asusd` 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.
|
but can also be used with non-asus laptops with reduced features.
|
||||||
|
|
||||||
@@ -8,11 +10,10 @@ but can also be used with non-asus laptops with reduced features.
|
|||||||
- `asusd`: The main system daemon. It is autostarted by a udev rule and systemd unit.
|
- `asusd`: The main system daemon. It is autostarted by a udev rule and systemd unit.
|
||||||
- `asusd-user`: The user level daemon. Currently will run an anime sequence, with RGB keyboard sequences soon.
|
- `asusd-user`: The user level daemon. Currently will run an anime sequence, with RGB keyboard sequences soon.
|
||||||
- `asusctl`: The CLI for interacting with the system daemon
|
- `asusctl`: The CLI for interacting with the system daemon
|
||||||
- `asus-notify`: A notification daemon with a user systemd unit that can be enabled.
|
|
||||||
|
|
||||||
## `asusd`
|
## `asusd`
|
||||||
|
|
||||||
`asusd` is the main system-level daemon which will control/load/save various settings in a safe way for the user, along with exposing a *safe* dbus interface for these interactions. This section covers only the daemon plus the various configuration file options.
|
`asusd` is the main system-level daemon which will control/load/save various settings in a safe way for the user, along with exposing a _safe_ dbus interface for these interactions. This section covers only the daemon plus the various configuration file options.
|
||||||
|
|
||||||
The functionality that `asusd` exposes is:
|
The functionality that `asusd` exposes is:
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ Almost all modern ASUS laptops have charging limit control now. This can be cont
|
|||||||
```json
|
```json
|
||||||
"bat_charge_limit": 80,
|
"bat_charge_limit": 80,
|
||||||
```
|
```
|
||||||
|
|
||||||
where the number is a percentage.
|
where the number is a percentage.
|
||||||
|
|
||||||
### Bios control
|
### Bios control
|
||||||
@@ -63,7 +65,7 @@ where the number is a percentage.
|
|||||||
Some options that you find in Armory Crate are available under this controller, so far there is:
|
Some options that you find in Armory Crate are available under this controller, so far there is:
|
||||||
|
|
||||||
- POST sound: this is the sound you hear on bios boot post
|
- POST sound: this is the sound you hear on bios boot post
|
||||||
- GPU MUX: this controls if the dGPU is the *only* GPU, making it the main GPU and disabling the iGPU
|
- GPU MUX: this controls if the dGPU is the _only_ GPU, making it the main GPU and disabling the iGPU
|
||||||
|
|
||||||
These options are not written to the config file as they are stored in efivars. The only way to change these is to use the exposed safe dbus methods, or use the `asusctl` CLI tool.
|
These options are not written to the config file as they are stored in efivars. The only way to change these is to use the exposed safe dbus methods, or use the `asusctl` CLI tool.
|
||||||
|
|
||||||
@@ -72,6 +74,7 @@ These options are not written to the config file as they are stored in efivars.
|
|||||||
asusctl can support setting a power profile via platform_profile drivers. This requires [power-profiles-daemon](https://gitlab.freedesktop.org/hadess/power-profiles-daemon) v0.10.0 minimum. It also requires the kernel patch for platform_profile support to be applied form [here](https://lkml.org/lkml/2021/8/18/1022) - this patch is merged to 5.15 kernel upstream.
|
asusctl can support setting a power profile via platform_profile drivers. This requires [power-profiles-daemon](https://gitlab.freedesktop.org/hadess/power-profiles-daemon) v0.10.0 minimum. It also requires the kernel patch for platform_profile support to be applied form [here](https://lkml.org/lkml/2021/8/18/1022) - this patch is merged to 5.15 kernel upstream.
|
||||||
|
|
||||||
A common use of asusctl is to bind the `fn+f5` (fan) key to `asusctl profile -n` to cycle through the 3 profiles:
|
A common use of asusctl is to bind the `fn+f5` (fan) key to `asusctl profile -n` to cycle through the 3 profiles:
|
||||||
|
|
||||||
1. Balanced
|
1. Balanced
|
||||||
2. Performance
|
2. Performance
|
||||||
3. Quiet
|
3. Quiet
|
||||||
@@ -97,7 +100,7 @@ There is one more controller; the support controller. The sole pupose of this co
|
|||||||
|
|
||||||
## asusd-user
|
## asusd-user
|
||||||
|
|
||||||
`asusd-user` is a usermode daemon. The intended purpose is to provide a method for users to run there own custom per-key keyboard effects and modes, AniMe sequences, and possibly their own profiles - all without overwriting the *base* system config. As such some parts of the system daemon will migrate to the user daemon over time with the expectation that the Linux system runs both.
|
`asusd-user` is a usermode daemon. The intended purpose is to provide a method for users to run there own custom per-key keyboard effects and modes, AniMe sequences, and possibly their own profiles - all without overwriting the _base_ system config. As such some parts of the system daemon will migrate to the user daemon over time with the expectation that the Linux system runs both.
|
||||||
|
|
||||||
As of now only AniMe is active in this with configuration in `~/.config/rog/`. On first run defaults are created that are intended to work as examples.
|
As of now only AniMe is active in this with configuration in `~/.config/rog/`. On first run defaults are created that are intended to work as examples.
|
||||||
|
|
||||||
@@ -177,6 +180,7 @@ An Aura config itself is a file with contents:
|
|||||||
```
|
```
|
||||||
|
|
||||||
If your laptop supports multizone, `"led"` can also be `"Zone": <one of the following>`
|
If your laptop supports multizone, `"led"` can also be `"Zone": <one of the following>`
|
||||||
|
|
||||||
- `SingleZone` // Keyboards with only one zone
|
- `SingleZone` // Keyboards with only one zone
|
||||||
- `ZonedKbLeft` // keyboard left
|
- `ZonedKbLeft` // keyboard left
|
||||||
- `ZonedKbLeftMid` // keyboard left-middle
|
- `ZonedKbLeftMid` // keyboard left-middle
|
||||||
@@ -238,6 +242,7 @@ Each object in the array can be one of:
|
|||||||
##### AsusAnimation
|
##### AsusAnimation
|
||||||
|
|
||||||
`AsusAnimation` is specifically for running the gif files that Armory Crate comes with. `asusctl` includes all of these in `/usr/share/asusd/anime/asus/`
|
`AsusAnimation` is specifically for running the gif files that Armory Crate comes with. `asusctl` includes all of these in `/usr/share/asusd/anime/asus/`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"AsusAnimation": {
|
"AsusAnimation": {
|
||||||
"file": "<FILE_PATH>",
|
"file": "<FILE_PATH>",
|
||||||
@@ -260,7 +265,7 @@ Virtually the same as `AsusAnimation` but for png files, typically created in th
|
|||||||
|
|
||||||
##### ImageAnimation
|
##### ImageAnimation
|
||||||
|
|
||||||
`ImageAnimation` can play *any* gif of any size.
|
`ImageAnimation` can play _any_ gif of any size.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"ImageAnimation": {
|
"ImageAnimation": {
|
||||||
@@ -319,6 +324,7 @@ Must be full path: `"/usr/share/asusd/anime/asus/gaming/Controller.gif"` or `/ho
|
|||||||
**<FLOAT>**
|
**<FLOAT>**
|
||||||
|
|
||||||
A number from 0.0-1.0.
|
A number from 0.0-1.0.
|
||||||
|
|
||||||
- `brightness`: If it is brightness it is combined with the system daemon global brightness
|
- `brightness`: If it is brightness it is combined with the system daemon global brightness
|
||||||
- `scale`: 1.0 is the original size with lower number shrinking, larger growing
|
- `scale`: 1.0 is the original size with lower number shrinking, larger growing
|
||||||
- `angle`: Rotation angle in radians
|
- `angle`: Rotation angle in radians
|
||||||
@@ -327,6 +333,7 @@ A number from 0.0-1.0.
|
|||||||
**<TIME>**
|
**<TIME>**
|
||||||
|
|
||||||
Time is the length of time to run the gif for:
|
Time is the length of time to run the gif for:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"time": {
|
"time": {
|
||||||
"Time": {
|
"Time": {
|
||||||
@@ -335,17 +342,23 @@ Time is the length of time to run the gif for:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
A cycle is how many gif loops to run:
|
A cycle is how many gif loops to run:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"time": {
|
"time": {
|
||||||
"Cycles": 2
|
"Cycles": 2
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
`Infinite` means that this gif will never end:
|
`Infinite` means that this gif will never end:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"time": "Infinite",
|
"time": "Infinite",
|
||||||
```
|
```
|
||||||
|
|
||||||
`Fade` allows an image or gif to fade in and out, and remain at max brightness to n time:
|
`Fade` allows an image or gif to fade in and out, and remain at max brightness to n time:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"time": {
|
"time": {
|
||||||
"Fade": {
|
"Fade": {
|
||||||
@@ -364,6 +377,7 @@ A cycle is how many gif loops to run:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
`show_for` can be `null`, if it is `null` then the `show_for` becomes `gif_time_length - fade_in - fade_out`.
|
`show_for` can be `null`, if it is `null` then the `show_for` becomes `gif_time_length - fade_in - fade_out`.
|
||||||
This is period for which the gif or image will be max brightness (as set).
|
This is period for which the gif or image will be max brightness (as set).
|
||||||
|
|
||||||
@@ -404,26 +418,19 @@ asusctl <command> <subcommand> --help
|
|||||||
|
|
||||||
To switch to next/previous Aura modes you will need to bind both the aura keys (if available) to one of:
|
To switch to next/previous Aura modes you will need to bind both the aura keys (if available) to one of:
|
||||||
**Next**
|
**Next**
|
||||||
|
|
||||||
```
|
```
|
||||||
asusctl led-mode -n
|
asusctl led-mode -n
|
||||||
```
|
```
|
||||||
|
|
||||||
**Previous**
|
**Previous**
|
||||||
|
|
||||||
```
|
```
|
||||||
asusctl led-mode -p
|
asusctl led-mode -p
|
||||||
```
|
```
|
||||||
|
|
||||||
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
||||||
|
|
||||||
## User NOTIFICATIONS via dbus
|
|
||||||
|
|
||||||
If you have a notifications handler set up, or are using KDE or Gnome then you
|
|
||||||
can enable the user service to get basic notifications when something changes.
|
|
||||||
|
|
||||||
```
|
|
||||||
systemctl --user enable asus-notify.service
|
|
||||||
systemctl --user start asus-notify.service
|
|
||||||
```
|
|
||||||
|
|
||||||
# License & Trademarks
|
# License & Trademarks
|
||||||
|
|
||||||
Mozilla Public License 2 (MPL-2.0)
|
Mozilla Public License 2 (MPL-2.0)
|
||||||
|
|||||||
@@ -123,14 +123,8 @@ bindings:
|
|||||||
typeshare ./rog-profiles/src/ --lang=typescript --output-file=bindings/ts/profiles.ts
|
typeshare ./rog-profiles/src/ --lang=typescript --output-file=bindings/ts/profiles.ts
|
||||||
typeshare ./rog-platform/src/ --lang=typescript --output-file=bindings/ts/platform.ts
|
typeshare ./rog-platform/src/ --lang=typescript --output-file=bindings/ts/platform.ts
|
||||||
|
|
||||||
introspect:
|
translate:
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Platform -x > bindings/dbus-xml/org-asuslinux-platform-4.xml
|
find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Aura -x > bindings/dbus-xml/org-asuslinux-aura-4.xml
|
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Anime -x > bindings/dbus-xml/org-asuslinux-anime-4.xml
|
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/FanCurves -x > bindings/dbus-xml/org-asuslinux-fan-curves-4.xml
|
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Introspectable"]' bindings/dbus-xml/org-asuslinux-*
|
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Properties"]' bindings/dbus-xml/org-asuslinux-*
|
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Peer"]' bindings/dbus-xml/org-asuslinux-*
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
ifeq ($(VENDORED),1)
|
ifeq ($(VENDORED),1)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[Become a Patron!](https://www.patreon.com/bePatron?u=7602281) - [Asus Linux Website](https://asus-linux.org/)
|
[Become a Patron!](https://www.patreon.com/bePatron?u=7602281) - [Asus Linux Website](https://asus-linux.org/)
|
||||||
|
|
||||||
**WARNING:** Many features are developed in tandem with kernel patches. If you see a feature is missing you either need a patched kernel, or v6.1 which has all my work merged upstream.
|
**WARNING:** Many features are developed in tandem with kernel patches. If you see a feature is missing you either need a patched kernel or latest release.
|
||||||
|
|
||||||
`asusd` is a utility for Linux to control many aspects of various ASUS laptops
|
`asusd` 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.
|
but can also be used with non-asus laptops with reduced features.
|
||||||
@@ -11,27 +11,27 @@ Now includes a GUI, `rog-control-center`.
|
|||||||
|
|
||||||
## Kernel support
|
## Kernel support
|
||||||
|
|
||||||
**The minimum supported kernel version is 5.17**
|
**The minimum supported kernel version is 6.10**, which will contain the patches from [here](https://lore.kernel.org/platform-driver-x86/20240404001652.86207-1-luke@ljones.dev/). Z13 devices will need [these](https://lore.kernel.org/linux-input/20240416090402.31057-1-luke@ljones.dev/T/#t)
|
||||||
|
|
||||||
**For TUF laptops, the minimum supported kernel version is 6.1**
|
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
1. To provide an interface for rootless control of some system functions most users wish to control such as fan speeds, keyboard LEDs, graphics modes.
|
The main goal of this work is to provide a safe and easy to use abstraction over various laptop features via DBUS, and to provide some helpful defaults and other behaviour such as toggling throttle/profile on AC/battery change.
|
||||||
2. Enable third-party apps to use the above with dbus methods
|
|
||||||
3. To make the above as easy as possible for new users
|
|
||||||
4. Respect the users resources: be small, light, and fast
|
|
||||||
|
|
||||||
Point 3 means that the list of supported distros is very narrow - fedora is explicitly
|
1. Provide safe dbus interface
|
||||||
supported. All other distros are *not* supported (while asusd might still run fine on them).
|
2. Respect the users resources: be small, light, and fast
|
||||||
For best support use fedora 36+ Workstation.
|
|
||||||
|
|
||||||
Point 4? asusd currently uses a tiny fraction of cpu time, and less than 1Mb of ram, the way
|
Point 4? asusd currently uses a tiny fraction of cpu time, and less than 1Mb of ram, the way
|
||||||
a system-level daemon should.
|
a system-level daemon should. Languages such as JS and python should never be used for system level daemons (please stop).
|
||||||
|
|
||||||
|
## Keyboard LEDs
|
||||||
|
|
||||||
|
The level of support for laptops is dependent on folks submitting data to include in [`./rog-aura/data/layouts/aura_support.ron`](./rog-aura/data/layouts/aura_support.ron), typically installed in `/usr/share/asusd/aura_support.ron`. This is because the controller used for keyboards and LEDs is used across many years and many laptop models, all with different firmware configurations - the only way to track this is with the file mentioned above. Why not just enable all by default? Because it confuses people.
|
||||||
|
|
||||||
|
See the [rog-aura readme](./rog-aura/README.md) for more details.
|
||||||
|
|
||||||
## Discord
|
## Discord
|
||||||
|
|
||||||
[Discord server link](https://discord.gg/WTHnqabm)
|
[Discord server link](https://discord.gg/z8y99XqPb7)
|
||||||
|
|
||||||
## SUPPORTED LAPTOPS
|
## SUPPORTED LAPTOPS
|
||||||
|
|
||||||
@@ -42,54 +42,42 @@ to this:
|
|||||||
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
|
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```
|
||||||
|
Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown]
|
||||||
|
```
|
||||||
|
|
||||||
then it may work without tweaks. Technically all other functions except the LED
|
then it may work without tweaks. Technically all other functions except the LED
|
||||||
and AniMe parts should work regardless of your latop make.
|
and AniMe parts should work regardless of your latop make.
|
||||||
|
|
||||||
## Implemented
|
## Implemented
|
||||||
|
|
||||||
- [X] System daemon
|
The list is a bit outdated as many features have been enabled in the Linux kernel with upstream patches and then supported in asusctl suite.
|
||||||
- [X] GUI app (includes tray and notifications)
|
|
||||||
- [X] Setting/modifying built-in LED modes
|
- [x] System daemon
|
||||||
- [X] Per-key LED setting
|
- [x] GUI app (includes tray and notifications)
|
||||||
- [X] Fancy LED modes (See examples) (currently being reworked)
|
- [x] Setting/modifying built-in LED modes
|
||||||
- [X] AniMatrix display on G14 and M16 models that include it
|
- [x] Per-key LED setting
|
||||||
- [X] Set battery charge limit (with kernel supporting this)
|
- [x] Fancy LED modes (See examples) (currently being reworked)
|
||||||
- [X] Fan curve control on supported laptops (G14/G15, some TUF like FA507)
|
- [x] AniMatrix display on G14 and M16 models that include it
|
||||||
- [X] Toggle bios setting for boot/POST sound
|
- [x] Set battery charge limit (with kernel supporting this)
|
||||||
- [X] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops)
|
- [x] Fan curve control on supported laptops (G14/G15, some TUF like FA507)
|
||||||
|
- [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.
|
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.
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
# BUILDING
|
# BUILDING
|
||||||
|
|
||||||
Requirements are rust >= 1.57 installed from rustup.io if the distro provided version is too old, and `make`.
|
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.
|
||||||
|
|
||||||
**Ubuntu (unsuported):**
|
|
||||||
|
|
||||||
apt install libgtk-3-dev libpango1.0-dev libgdk-pixbuf-2.0-dev libglib2.0-dev cmake libclang-dev libudev-dev libayatana-appindicator3-1
|
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
||||||
source "$HOME/.cargo/env"
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
**popos (unsuported):**
|
|
||||||
|
|
||||||
sudo apt install cmake libclang-dev libudev-dev libgtk-3-dev libclang-dev libglib2.0-dev libatkmm-1.6-dev libpangomm-1.4-dev librust-gdk-pixbuf-dev
|
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
||||||
source "$HOME/.cargo/env"
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
|
|
||||||
**fedora:**
|
**fedora:**
|
||||||
|
|
||||||
dnf install cmake clang-devel systemd-devel glib2-devel cairo-devel atkmm-devel pangomm-devel gdk-pixbuf2-devel gtk3-devel libappindicator-gtk3
|
dnf install cmake clang-devel libinput-devel libseat-devel libgbm-devel libxkbcommon-devel systemd-devel \
|
||||||
|
libdrm-devel expat-devel pcre2-devel libzstd-devel libappindicator-gtk3
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
||||||
@@ -98,28 +86,34 @@ Requirements are rust >= 1.57 installed from rustup.io if the distro provided ve
|
|||||||
Works with KDE Plasma (without GTK packages)
|
Works with KDE Plasma (without GTK packages)
|
||||||
|
|
||||||
zypper in -t pattern devel_basis
|
zypper in -t pattern devel_basis
|
||||||
zypper in rustup make cmake systemd-devel clang-devel llvm-devel gdk-pixbuf-devel cairo-devel pango-devel freetype-devel gtk3-devel libexpat-devel libayatana-indicator3-7
|
zypper in rustup make cmake libinput-devel libseat-devel libgbm-devel systemd-devel clang-devel llvm-devel gdk-pixbuf-devel cairo-devel pango-devel freetype-devel libexpat-devel libayatana-indicator3-7
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
||||||
|
**Ubuntu, Popos (unsuported):**
|
||||||
|
|
||||||
|
instructions removed as outdated
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
- Fedora copr = https://copr.fedorainfracloud.org/coprs/lukenukem/asus-linux/
|
- Fedora copr = https://copr.fedorainfracloud.org/coprs/lukenukem/asus-linux/
|
||||||
- openSUSE = https://download.opensuse.org/repositories/home:/luke_nukem:/asus/
|
- openSUSE = https://download.opensuse.org/repositories/home:/luke_nukem:/asus/
|
||||||
- Ubuntu = not supported due to packaging woes, but you can build and install on your own.
|
|
||||||
|
|
||||||
=======
|
=======
|
||||||
|
|
||||||
The default init method is to use the udev rule, this ensures that the service is
|
The default init method is to use the udev rule, this ensures that the service is
|
||||||
started when the device is initialised and ready.
|
started when the device is initialised and ready.
|
||||||
|
|
||||||
|
You may also need to activate the service for debian install. If running Pop!\_OS, I suggest disabling `system76-power` gnome-shell extension and systemd service.
|
||||||
|
|
||||||
|
## Upgrading
|
||||||
|
|
||||||
If you are upgrading from a previous installed version, you will need to restart the service or reboot.
|
If you are upgrading from a previous installed version, you will need to restart the service or reboot.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ systemctl daemon-reload && systemctl restart asusd
|
$ systemctl daemon-reload && systemctl restart asusd
|
||||||
```
|
```
|
||||||
|
|
||||||
You may also need to activate the service for debian install. If running Pop!_OS, I suggest disabling `system76-power` gnome-shell extension and systemd service.
|
|
||||||
|
|
||||||
## Uninstalling
|
## Uninstalling
|
||||||
|
|
||||||
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
||||||
@@ -136,7 +130,7 @@ Dbus introsepction XML requires with `make introspection` requires `anime_sim` t
|
|||||||
|
|
||||||
## AniMe Matrix simulator
|
## AniMe Matrix simulator
|
||||||
|
|
||||||
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop *with* the display, the simulated display will be used instead of the physical display.
|
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display.
|
||||||
|
|
||||||
## Supporting more laptops
|
## Supporting more laptops
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ version.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
|
rog_slash = { path = "../rog-slash" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
@@ -16,11 +17,14 @@ dmi_id = { path = "../dmi-id" }
|
|||||||
|
|
||||||
gumdrop.workspace = true
|
gumdrop.workspace = true
|
||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
|
zbus.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gif.workspace = true
|
gif.workspace = true
|
||||||
tinybmp.workspace = true
|
tinybmp.workspace = true
|
||||||
glam.workspace = true
|
glam.workspace = true
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
|
tokio.workspace = true
|
||||||
|
|
||||||
cargo-husky.workspace = true
|
cargo-husky.workspace = true
|
||||||
@@ -5,10 +5,12 @@ use std::process::exit;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimeDiagonal, AnimeType};
|
use rog_anime::{AnimeDiagonal, AnimeType};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
@@ -26,11 +28,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let anime_type = get_anime_type()?;
|
let anime_type = get_anime_type()?;
|
||||||
|
|
||||||
client
|
proxy.write(matrix.into_data_buffer(anime_type)?).unwrap();
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(matrix.into_data_buffer(anime_type)?)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimeDiagonal, AnimeType};
|
use rog_anime::{AnimeDiagonal, AnimeType};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
// In usable data:
|
// In usable data:
|
||||||
// Top row start at 1, ends at 32
|
// Top row start at 1, ends at 32
|
||||||
@@ -11,7 +12,8 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
// 74w x 36h diagonal used by the windows app
|
// 74w x 36h diagonal used by the windows app
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
for step in (2..50).rev() {
|
for step in (2..50).rev() {
|
||||||
let mut matrix = AnimeDiagonal::new(AnimeType::GA401, None);
|
let mut matrix = AnimeDiagonal::new(AnimeType::GA401, None);
|
||||||
@@ -28,9 +30,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let anime_type = get_anime_type().unwrap();
|
let anime_type = get_anime_type().unwrap();
|
||||||
client
|
proxy
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(matrix.into_data_buffer(anime_type).unwrap())
|
.write(matrix.into_data_buffer(anime_type).unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
sleep(Duration::from_millis(300));
|
sleep(Duration::from_millis(300));
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ use std::thread::sleep;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{ActionData, ActionLoader, Sequences};
|
use rog_anime::{ActionData, ActionLoader, Sequences};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
@@ -33,11 +35,7 @@ fn main() {
|
|||||||
for action in seq.iter() {
|
for action in seq.iter() {
|
||||||
if let ActionData::Animation(frames) = action {
|
if let ActionData::Animation(frames) = action {
|
||||||
for frame in frames.frames() {
|
for frame in frames.frames() {
|
||||||
client
|
proxy.write(frame.frame().clone()).unwrap();
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(frame.frame().clone())
|
|
||||||
.unwrap();
|
|
||||||
sleep(frame.delay());
|
sleep(frame.delay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ use std::convert::TryFrom;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimeDataBuffer, AnimeGrid};
|
use rog_anime::{AnimeDataBuffer, AnimeGrid};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
// In usable data:
|
// In usable data:
|
||||||
// Top row start at 1, ends at 32
|
// Top row start at 1, ends at 32
|
||||||
@@ -10,7 +11,9 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
// 74w x 36h diagonal used by the windows app
|
// 74w x 36h diagonal used by the windows app
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let anime_type = get_anime_type().unwrap();
|
let anime_type = get_anime_type().unwrap();
|
||||||
let mut matrix = AnimeGrid::new(anime_type);
|
let mut matrix = AnimeGrid::new(anime_type);
|
||||||
let tmp = matrix.get_mut();
|
let tmp = matrix.get_mut();
|
||||||
@@ -43,5 +46,5 @@ fn main() {
|
|||||||
|
|
||||||
let matrix = <AnimeDataBuffer>::try_from(matrix).unwrap();
|
let matrix = <AnimeDataBuffer>::try_from(matrix).unwrap();
|
||||||
|
|
||||||
client.proxies().anime().write(matrix).unwrap();
|
proxy.write(matrix).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::AnimeDataBuffer;
|
use rog_anime::AnimeDataBuffer;
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
// In usable data:
|
// In usable data:
|
||||||
// Top row start at 1, ends at 32
|
// Top row start at 1, ends at 32
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
let anime_type = get_anime_type().unwrap();
|
let anime_type = get_anime_type().unwrap();
|
||||||
let mut matrix = AnimeDataBuffer::new(anime_type);
|
let mut matrix = AnimeDataBuffer::new(anime_type);
|
||||||
matrix.data_mut()[1] = 100; // start = 1
|
matrix.data_mut()[1] = 100; // start = 1
|
||||||
@@ -127,5 +129,5 @@ fn main() {
|
|||||||
matrix.data_mut()[1244] = 100; // end
|
matrix.data_mut()[1244] = 100; // end
|
||||||
println!("{:?}", &matrix);
|
println!("{:?}", &matrix);
|
||||||
|
|
||||||
client.proxies().anime().write(matrix).unwrap();
|
proxy.write(matrix).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ use std::process::exit;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2};
|
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 7 {
|
if args.len() != 7 {
|
||||||
@@ -31,11 +33,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
anime_type,
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
client
|
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?).unwrap();
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(<AnimeDataBuffer>::try_from(&matrix)?)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2};
|
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 7 {
|
if args.len() != 7 {
|
||||||
@@ -41,11 +43,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
matrix.update();
|
matrix.update();
|
||||||
|
|
||||||
client
|
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?).unwrap();
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(<AnimeDataBuffer>::try_from(&matrix)?)
|
|
||||||
.unwrap();
|
|
||||||
sleep(Duration::from_micros(500));
|
sleep(Duration::from_micros(500));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
//! Using a combination of key-colour array plus a key layout to generate
|
//! Using a combination of key-colour array plus a key layout to generate
|
||||||
//! outputs.
|
//! outputs.
|
||||||
|
|
||||||
use rog_aura::advanced::LedCode;
|
|
||||||
use rog_aura::effects::{AdvancedEffects, Effect};
|
use rog_aura::effects::{AdvancedEffects, Effect};
|
||||||
use rog_aura::layouts::KeyLayout;
|
use rog_aura::keyboard::{KeyLayout, LedCode};
|
||||||
use rog_aura::Colour;
|
use rog_aura::Colour;
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let layout = KeyLayout::default_layout();
|
let layout = KeyLayout::default_layout();
|
||||||
|
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let conn = Connection::system().unwrap();
|
||||||
|
let proxy = AuraProxyBlocking::new(&conn).unwrap();
|
||||||
|
|
||||||
let mut seq = AdvancedEffects::new(true);
|
let mut seq = AdvancedEffects::new(true);
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
seq.next_state(&layout);
|
seq.next_state(&layout);
|
||||||
let packets = seq.create_packets();
|
let packets = seq.create_packets();
|
||||||
|
|
||||||
client.proxies().aura().direct_addressing_raw(packets)?;
|
proxy.direct_addressing_raw(packets)?;
|
||||||
std::thread::sleep(std::time::Duration::from_millis(33));
|
std::thread::sleep(std::time::Duration::from_millis(33));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-16
@@ -10,10 +10,10 @@ pub struct LedPowerCommand1 {
|
|||||||
pub help: bool,
|
pub help: bool,
|
||||||
#[options(meta = "", help = "Control if LEDs enabled while awake <true/false>")]
|
#[options(meta = "", help = "Control if LEDs enabled while awake <true/false>")]
|
||||||
pub awake: Option<bool>,
|
pub awake: Option<bool>,
|
||||||
#[options(meta = "", help = "Use with awake option <true/false>")]
|
#[options(help = "Use with awake option, if excluded defaults to false")]
|
||||||
pub keyboard: Option<bool>,
|
pub keyboard: bool,
|
||||||
#[options(meta = "", help = "Use with awake option <true/false>")]
|
#[options(help = "Use with awake option, if excluded defaults to false")]
|
||||||
pub lightbar: Option<bool>,
|
pub lightbar: bool,
|
||||||
#[options(meta = "", help = "Control boot animations <true/false>")]
|
#[options(meta = "", help = "Control boot animations <true/false>")]
|
||||||
pub boot: Option<bool>,
|
pub boot: Option<bool>,
|
||||||
#[options(meta = "", help = "Control suspend animations <true/false>")]
|
#[options(meta = "", help = "Control suspend animations <true/false>")]
|
||||||
@@ -214,29 +214,29 @@ pub struct MultiColourSpeed {
|
|||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub enum SetAuraBuiltin {
|
pub enum SetAuraBuiltin {
|
||||||
#[options(help = "set a single static colour")]
|
#[options(help = "set a single static colour")]
|
||||||
Static(SingleColour),
|
Static(SingleColour), // 0
|
||||||
#[options(help = "pulse between one or two colours")]
|
#[options(help = "pulse between one or two colours")]
|
||||||
Breathe(TwoColourSpeed),
|
Breathe(TwoColourSpeed), // 1
|
||||||
#[options(help = "strobe through all colours")]
|
#[options(help = "strobe through all colours")]
|
||||||
Strobe(SingleSpeed),
|
Strobe(SingleSpeed), // 2
|
||||||
#[options(help = "rainbow cycling in one of four directions")]
|
#[options(help = "rainbow cycling in one of four directions")]
|
||||||
Rainbow(SingleSpeedDirection),
|
Rainbow(SingleSpeedDirection), // 3
|
||||||
#[options(help = "rain pattern mimicking raindrops")]
|
#[options(help = "rain pattern mimicking raindrops")]
|
||||||
Stars(TwoColourSpeed),
|
Stars(TwoColourSpeed), // 4
|
||||||
#[options(help = "rain pattern of three preset colours")]
|
#[options(help = "rain pattern of three preset colours")]
|
||||||
Rain(SingleSpeed),
|
Rain(SingleSpeed), // 5
|
||||||
#[options(help = "pressed keys are highlighted to fade")]
|
#[options(help = "pressed keys are highlighted to fade")]
|
||||||
Highlight(SingleColourSpeed),
|
Highlight(SingleColourSpeed), // 6
|
||||||
#[options(help = "pressed keys generate horizontal laser")]
|
#[options(help = "pressed keys generate horizontal laser")]
|
||||||
Laser(SingleColourSpeed),
|
Laser(SingleColourSpeed), // 7
|
||||||
#[options(help = "pressed keys ripple outwards like a splash")]
|
#[options(help = "pressed keys ripple outwards like a splash")]
|
||||||
Ripple(SingleColourSpeed),
|
Ripple(SingleColourSpeed), // 8
|
||||||
#[options(help = "set a rapid pulse")]
|
#[options(help = "set a rapid pulse")]
|
||||||
Pulse(SingleColour),
|
Pulse(SingleColour), // 10
|
||||||
#[options(help = "set a vertical line zooming from left")]
|
#[options(help = "set a vertical line zooming from left")]
|
||||||
Comet(SingleColour),
|
Comet(SingleColour), // 11
|
||||||
#[options(help = "set a wide vertical line zooming from left")]
|
#[options(help = "set a wide vertical line zooming from left")]
|
||||||
Flash(SingleColour),
|
Flash(SingleColour), // 12
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SetAuraBuiltin {
|
impl Default for SetAuraBuiltin {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use rog_platform::platform::PlatformPolicy;
|
use rog_platform::platform::ThrottlePolicy;
|
||||||
|
|
||||||
use crate::anime_cli::AnimeCommand;
|
use crate::anime_cli::AnimeCommand;
|
||||||
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
||||||
use crate::fan_curve_cli::FanCurveCommand;
|
use crate::fan_curve_cli::FanCurveCommand;
|
||||||
|
use crate::slash_cli::SlashCommand;
|
||||||
|
|
||||||
#[derive(Default, Options)]
|
#[derive(Default, Options)]
|
||||||
pub struct CliStart {
|
pub struct CliStart {
|
||||||
@@ -41,6 +42,8 @@ pub enum CliCommand {
|
|||||||
Graphics(GraphicsCommand),
|
Graphics(GraphicsCommand),
|
||||||
#[options(name = "anime", help = "Manage AniMe Matrix")]
|
#[options(name = "anime", help = "Manage AniMe Matrix")]
|
||||||
Anime(AnimeCommand),
|
Anime(AnimeCommand),
|
||||||
|
#[options(name = "slash", help = "Manage Slash Ledbar")]
|
||||||
|
Slash(SlashCommand),
|
||||||
#[options(help = "Change bios settings")]
|
#[options(help = "Change bios settings")]
|
||||||
Bios(BiosCommand),
|
Bios(BiosCommand),
|
||||||
}
|
}
|
||||||
@@ -60,7 +63,7 @@ pub struct ProfileCommand {
|
|||||||
pub profile_get: bool,
|
pub profile_get: bool,
|
||||||
|
|
||||||
#[options(meta = "", help = "set the active profile")]
|
#[options(meta = "", help = "set the active profile")]
|
||||||
pub profile_set: Option<PlatformPolicy>,
|
pub profile_set: Option<ThrottlePolicy>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use rog_platform::platform::PlatformPolicy;
|
use rog_platform::platform::ThrottlePolicy;
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
use rog_profiles::fan_curve_set::CurveData;
|
||||||
use rog_profiles::FanCurvePU;
|
use rog_profiles::FanCurvePU;
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ pub struct FanCurveCommand {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "profile to modify fan-curve for. Shows data if no options provided"
|
help = "profile to modify fan-curve for. Shows data if no options provided"
|
||||||
)]
|
)]
|
||||||
pub mod_profile: Option<PlatformPolicy>,
|
pub mod_profile: Option<ThrottlePolicy>,
|
||||||
|
|
||||||
#[options(
|
#[options(
|
||||||
meta = "",
|
meta = "",
|
||||||
|
|||||||
+336
-265
@@ -5,7 +5,6 @@ use std::process::Command;
|
|||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
use anime_cli::{AnimeActions, AnimeCommand};
|
use anime_cli::{AnimeActions, AnimeCommand};
|
||||||
use asusd::ctrl_aura::trait_impls::AURA_ZBUS_NAME;
|
|
||||||
use asusd::ctrl_fancurves::FAN_CURVE_ZBUS_NAME;
|
use asusd::ctrl_fancurves::FAN_CURVE_ZBUS_NAME;
|
||||||
use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
@@ -13,21 +12,27 @@ use fan_curve_cli::FanCurveCommand;
|
|||||||
use gumdrop::{Opt, Options};
|
use gumdrop::{Opt, Options};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||||
use rog_aura::power::KbAuraPowerState;
|
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraPowerDev};
|
use rog_aura::{self, AuraDeviceType, AuraEffect, PowerZones};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||||
use rog_platform::error::PlatformError;
|
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
||||||
use rog_platform::platform::{GpuMode, PlatformPolicy, Properties};
|
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||||
|
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
||||||
|
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
|
use rog_slash::SlashMode;
|
||||||
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
use crate::aura_cli::{AuraPowerStates, LedBrightness};
|
use crate::aura_cli::{AuraPowerStates, LedBrightness};
|
||||||
use crate::cli_opts::*;
|
use crate::cli_opts::*;
|
||||||
|
use crate::slash_cli::SlashCommand;
|
||||||
|
|
||||||
mod anime_cli;
|
mod anime_cli;
|
||||||
mod aura_cli;
|
mod aura_cli;
|
||||||
mod cli_opts;
|
mod cli_opts;
|
||||||
mod fan_curve_cli;
|
mod fan_curve_cli;
|
||||||
|
mod slash_cli;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = args().skip(1).collect();
|
let args: Vec<String> = args().skip(1).collect();
|
||||||
@@ -45,13 +50,21 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok((dbus, _)) = RogDbusClientBlocking::new().map_err(|e| {
|
let conn = Connection::system().unwrap();
|
||||||
|
if let Ok(platform_proxy) = PlatformProxyBlocking::new(&conn).map_err(|e| {
|
||||||
check_service("asusd");
|
check_service("asusd");
|
||||||
println!("\nError: {e}\n");
|
println!("\nError: {e}\n");
|
||||||
print_info();
|
print_info();
|
||||||
}) {
|
}) {
|
||||||
let supported_properties = dbus.proxies().platform().supported_properties().unwrap();
|
let self_version = env!("CARGO_PKG_VERSION");
|
||||||
let supported_interfaces = dbus.proxies().platform().supported_interfaces().unwrap();
|
let asusd_version = platform_proxy.version().unwrap();
|
||||||
|
if asusd_version != self_version {
|
||||||
|
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let supported_properties = platform_proxy.supported_properties().unwrap();
|
||||||
|
let supported_interfaces = platform_proxy.supported_interfaces().unwrap();
|
||||||
|
|
||||||
if parsed.version {
|
if parsed.version {
|
||||||
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||||
@@ -59,7 +72,7 @@ fn main() {
|
|||||||
print_info();
|
print_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = do_parsed(&parsed, &supported_interfaces, &supported_properties, &dbus) {
|
if let Err(err) = do_parsed(&parsed, &supported_interfaces, &supported_properties, conn) {
|
||||||
print_error_help(&*err, &supported_interfaces, &supported_properties);
|
print_error_help(&*err, &supported_interfaces, &supported_properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,23 +117,68 @@ fn check_service(name: &str) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_aura_iface() -> Result<Vec<AuraProxyBlocking<'static>>, Box<dyn std::error::Error>> {
|
||||||
|
let conn = zbus::blocking::Connection::system().unwrap();
|
||||||
|
let f = zbus::blocking::fdo::ObjectManagerProxy::new(
|
||||||
|
&conn,
|
||||||
|
"org.asuslinux.Daemon",
|
||||||
|
"/org/asuslinux",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let interfaces = f.get_managed_objects().unwrap();
|
||||||
|
let mut aura_paths = Vec::new();
|
||||||
|
for v in interfaces.iter() {
|
||||||
|
// let o: Vec<zbus::names::OwnedInterfaceName> = v.1.keys().map(|e|
|
||||||
|
// e.to_owned()).collect(); println!("{}, {:?}", v.0, o);
|
||||||
|
for k in v.1.keys() {
|
||||||
|
if k.as_str() == "org.asuslinux.Aura" {
|
||||||
|
println!("Found aura device at {}, {}", v.0, k);
|
||||||
|
aura_paths.push(v.0.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if aura_paths.len() > 1 {
|
||||||
|
println!("Multiple aura devices found: {aura_paths:?}");
|
||||||
|
println!("TODO: enable selection");
|
||||||
|
}
|
||||||
|
if !aura_paths.is_empty() {
|
||||||
|
let mut ctrl = Vec::new();
|
||||||
|
for path in aura_paths {
|
||||||
|
ctrl.push(
|
||||||
|
AuraProxyBlocking::builder(&conn)
|
||||||
|
.path(path.clone())?
|
||||||
|
.destination("org.asuslinux.Daemon")?
|
||||||
|
.build()?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Ok(ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err("No Aura interface".into())
|
||||||
|
}
|
||||||
|
|
||||||
fn do_parsed(
|
fn do_parsed(
|
||||||
parsed: &CliStart,
|
parsed: &CliStart,
|
||||||
supported_interfaces: &[String],
|
supported_interfaces: &[String],
|
||||||
supported_properties: &[Properties],
|
supported_properties: &[Properties],
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
conn: Connection,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match &parsed.command {
|
match &parsed.command {
|
||||||
Some(CliCommand::LedMode(mode)) => handle_led_mode(dbus, supported_interfaces, mode)?,
|
Some(CliCommand::LedMode(mode)) => handle_led_mode(&find_aura_iface()?, mode)?,
|
||||||
Some(CliCommand::LedPow1(pow)) => handle_led_power1(dbus, supported_interfaces, pow)?,
|
Some(CliCommand::LedPow1(pow)) => handle_led_power1(&find_aura_iface()?, pow)?,
|
||||||
Some(CliCommand::LedPow2(pow)) => handle_led_power2(dbus, supported_interfaces, pow)?,
|
Some(CliCommand::LedPow2(pow)) => handle_led_power2(&find_aura_iface()?, pow)?,
|
||||||
Some(CliCommand::Profile(cmd)) => handle_throttle_profile(dbus, supported_properties, cmd)?,
|
Some(CliCommand::Profile(cmd)) => {
|
||||||
|
handle_throttle_profile(&conn, supported_properties, cmd)?
|
||||||
|
}
|
||||||
Some(CliCommand::FanCurve(cmd)) => {
|
Some(CliCommand::FanCurve(cmd)) => {
|
||||||
handle_fan_curve(dbus, supported_interfaces, cmd)?;
|
handle_fan_curve(&conn, supported_interfaces, cmd)?;
|
||||||
}
|
}
|
||||||
Some(CliCommand::Graphics(_)) => do_gfx(),
|
Some(CliCommand::Graphics(_)) => do_gfx(),
|
||||||
Some(CliCommand::Anime(cmd)) => handle_anime(dbus, cmd)?,
|
Some(CliCommand::Anime(cmd)) => handle_anime(&conn, cmd)?,
|
||||||
Some(CliCommand::Bios(cmd)) => handle_platform_properties(dbus, supported_properties, cmd)?,
|
Some(CliCommand::Slash(cmd)) => handle_slash(&conn, cmd)?,
|
||||||
|
Some(CliCommand::Bios(cmd)) => {
|
||||||
|
handle_platform_properties(&conn, supported_properties, cmd)?
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
if (!parsed.show_supported
|
if (!parsed.show_supported
|
||||||
&& parsed.kbd_bright.is_none()
|
&& parsed.kbd_bright.is_none()
|
||||||
@@ -132,16 +190,25 @@ fn do_parsed(
|
|||||||
println!("{}", CliStart::usage());
|
println!("{}", CliStart::usage());
|
||||||
println!();
|
println!();
|
||||||
if let Some(cmdlist) = CliStart::command_list() {
|
if let Some(cmdlist) = CliStart::command_list() {
|
||||||
|
let dev_type = if let Ok(proxy) = find_aura_iface() {
|
||||||
|
// TODO: commands on all?
|
||||||
|
proxy
|
||||||
|
.first()
|
||||||
|
.unwrap()
|
||||||
|
.device_type()
|
||||||
|
.unwrap_or(AuraDeviceType::Unknown)
|
||||||
|
} else {
|
||||||
|
AuraDeviceType::Unknown
|
||||||
|
};
|
||||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||||
for command in commands.iter().filter(|command| {
|
for command in commands.iter().filter(|command| {
|
||||||
let dev_type = dbus.proxies().aura().device_type().unwrap();
|
if !dev_type.is_old_laptop()
|
||||||
if !dev_type.is_old_style()
|
&& !dev_type.is_tuf_laptop()
|
||||||
&& !dev_type.is_tuf_style()
|
|
||||||
&& command.trim().starts_with("led-pow-1")
|
&& command.trim().starts_with("led-pow-1")
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !dev_type.is_new_style() && command.trim().starts_with("led-pow-2") {
|
if !dev_type.is_new_laptop() && command.trim().starts_with("led-pow-2") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -158,37 +225,67 @@ fn do_parsed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(brightness) = &parsed.kbd_bright {
|
if let Some(brightness) = &parsed.kbd_bright {
|
||||||
match brightness.level() {
|
if let Ok(aura) = find_aura_iface() {
|
||||||
None => {
|
for aura in aura.iter() {
|
||||||
let level = dbus.proxies().aura().brightness()?;
|
match brightness.level() {
|
||||||
println!("Current keyboard led brightness: {level:?}");
|
None => {
|
||||||
|
let level = aura.brightness()?;
|
||||||
|
println!("Current keyboard led brightness: {level:?}");
|
||||||
|
}
|
||||||
|
Some(level) => aura.set_brightness(rog_aura::LedBrightness::from(level))?,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(level) => dbus
|
} else {
|
||||||
.proxies()
|
println!("No aura interface found");
|
||||||
.aura()
|
|
||||||
.set_brightness(rog_aura::LedBrightness::from(level))?,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsed.next_kbd_bright {
|
if parsed.next_kbd_bright {
|
||||||
let brightness = dbus.proxies().aura().brightness()?;
|
if let Ok(aura) = find_aura_iface() {
|
||||||
dbus.proxies().aura().set_brightness(brightness.next())?;
|
for aura in aura.iter() {
|
||||||
|
let brightness = aura.brightness()?;
|
||||||
|
aura.set_brightness(brightness.next())?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("No aura interface found");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsed.prev_kbd_bright {
|
if parsed.prev_kbd_bright {
|
||||||
let brightness = dbus.proxies().aura().brightness()?;
|
if let Ok(aura) = find_aura_iface() {
|
||||||
dbus.proxies().aura().set_brightness(brightness.prev())?;
|
for aura in aura.iter() {
|
||||||
|
let brightness = aura.brightness()?;
|
||||||
|
aura.set_brightness(brightness.prev())?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("No aura interface found");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
if parsed.show_supported {
|
||||||
// if parsed.show_supported {
|
println!("Supported Core Functions:\n{:#?}", supported_interfaces);
|
||||||
// println!("Supported laptop functions:\n\n{}", supported);
|
println!(
|
||||||
// }
|
"Supported Platform Properties:\n{:#?}",
|
||||||
|
supported_properties
|
||||||
|
);
|
||||||
|
if let Ok(aura) = find_aura_iface() {
|
||||||
|
// TODO: multiple RGB check
|
||||||
|
let bright = aura.first().unwrap().supported_brightness()?;
|
||||||
|
let modes = aura.first().unwrap().supported_basic_modes()?;
|
||||||
|
let zones = aura.first().unwrap().supported_basic_zones()?;
|
||||||
|
let power = aura.first().unwrap().supported_power_zones()?;
|
||||||
|
println!("Supported Keyboard Brightness:\n{:#?}", bright);
|
||||||
|
println!("Supported Aura Modes:\n{:#?}", modes);
|
||||||
|
println!("Supported Aura Zones:\n{:#?}", zones);
|
||||||
|
println!("Supported Aura Power Zones:\n{:#?}", power);
|
||||||
|
} else {
|
||||||
|
println!("No aura interface found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(chg_limit) = parsed.chg_limit {
|
if let Some(chg_limit) = parsed.chg_limit {
|
||||||
dbus.proxies()
|
let proxy = PlatformProxyBlocking::new(&conn)?;
|
||||||
.platform()
|
proxy.set_charge_control_end_threshold(chg_limit)?;
|
||||||
.set_charge_control_end_threshold(chg_limit)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -202,10 +299,7 @@ fn do_gfx() {
|
|||||||
println!("This command will be removed in future");
|
println!("This command will be removed in future");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_anime(
|
fn handle_anime(conn: &Connection, cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
|
||||||
cmd: &AnimeCommand,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if (cmd.command.is_none()
|
if (cmd.command.is_none()
|
||||||
&& cmd.enable_display.is_none()
|
&& cmd.enable_display.is_none()
|
||||||
&& cmd.enable_powersave_anim.is_none()
|
&& cmd.enable_powersave_anim.is_none()
|
||||||
@@ -222,23 +316,24 @@ fn handle_anime(
|
|||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let proxy = AnimeProxyBlocking::new(conn)?;
|
||||||
if let Some(enable) = cmd.enable_display {
|
if let Some(enable) = cmd.enable_display {
|
||||||
dbus.proxies().anime().set_enable_display(enable)?;
|
proxy.set_enable_display(enable)?;
|
||||||
}
|
}
|
||||||
if let Some(enable) = cmd.enable_powersave_anim {
|
if let Some(enable) = cmd.enable_powersave_anim {
|
||||||
dbus.proxies().anime().set_builtins_enabled(enable)?;
|
proxy.set_builtins_enabled(enable)?;
|
||||||
}
|
}
|
||||||
if let Some(bright) = cmd.brightness {
|
if let Some(bright) = cmd.brightness {
|
||||||
dbus.proxies().anime().set_brightness(bright)?;
|
proxy.set_brightness(bright)?;
|
||||||
}
|
}
|
||||||
if let Some(enable) = cmd.off_when_lid_closed {
|
if let Some(enable) = cmd.off_when_lid_closed {
|
||||||
dbus.proxies().anime().set_off_when_lid_closed(enable)?;
|
proxy.set_off_when_lid_closed(enable)?;
|
||||||
}
|
}
|
||||||
if let Some(enable) = cmd.off_when_suspended {
|
if let Some(enable) = cmd.off_when_suspended {
|
||||||
dbus.proxies().anime().set_off_when_suspended(enable)?;
|
proxy.set_off_when_suspended(enable)?;
|
||||||
}
|
}
|
||||||
if let Some(enable) = cmd.off_when_unplugged {
|
if let Some(enable) = cmd.off_when_unplugged {
|
||||||
dbus.proxies().anime().set_off_when_unplugged(enable)?;
|
proxy.set_off_when_unplugged(enable)?;
|
||||||
}
|
}
|
||||||
if cmd.off_with_his_head.is_some() {
|
if cmd.off_with_his_head.is_some() {
|
||||||
println!("Did Alice _really_ make it back from Wonderland?");
|
println!("Did Alice _really_ make it back from Wonderland?");
|
||||||
@@ -254,7 +349,7 @@ fn handle_anime(
|
|||||||
if cmd.clear {
|
if cmd.clear {
|
||||||
let data = vec![255u8; anime_type.data_length()];
|
let data = vec![255u8; anime_type.data_length()];
|
||||||
let tmp = AnimeDataBuffer::from_vec(anime_type, data)?;
|
let tmp = AnimeDataBuffer::from_vec(anime_type, data)?;
|
||||||
dbus.proxies().anime().write(tmp)?;
|
proxy.write(tmp)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(action) = cmd.command.as_ref() {
|
if let Some(action) = cmd.command.as_ref() {
|
||||||
@@ -278,9 +373,7 @@ fn handle_anime(
|
|||||||
anime_type,
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
dbus.proxies()
|
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?)?;
|
||||||
.anime()
|
|
||||||
.write(<AnimeDataBuffer>::try_from(&matrix)?)?;
|
|
||||||
}
|
}
|
||||||
AnimeActions::PixelImage(image) => {
|
AnimeActions::PixelImage(image) => {
|
||||||
if image.help_requested() || image.path.is_empty() {
|
if image.help_requested() || image.path.is_empty() {
|
||||||
@@ -299,9 +392,7 @@ fn handle_anime(
|
|||||||
anime_type,
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
dbus.proxies()
|
proxy.write(matrix.into_data_buffer(anime_type)?)?;
|
||||||
.anime()
|
|
||||||
.write(matrix.into_data_buffer(anime_type)?)?;
|
|
||||||
}
|
}
|
||||||
AnimeActions::Gif(gif) => {
|
AnimeActions::Gif(gif) => {
|
||||||
if gif.help_requested() || gif.path.is_empty() {
|
if gif.help_requested() || gif.path.is_empty() {
|
||||||
@@ -326,7 +417,7 @@ fn handle_anime(
|
|||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
loop {
|
loop {
|
||||||
for frame in matrix.frames() {
|
for frame in matrix.frames() {
|
||||||
dbus.proxies().anime().write(frame.frame().clone())?;
|
proxy.write(frame.frame().clone())?;
|
||||||
sleep(frame.delay());
|
sleep(frame.delay());
|
||||||
}
|
}
|
||||||
if loops >= 0 {
|
if loops >= 0 {
|
||||||
@@ -357,7 +448,7 @@ fn handle_anime(
|
|||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
loop {
|
loop {
|
||||||
for frame in matrix.frames() {
|
for frame in matrix.frames() {
|
||||||
dbus.proxies().anime().write(frame.frame().clone())?;
|
proxy.write(frame.frame().clone())?;
|
||||||
sleep(frame.delay());
|
sleep(frame.delay());
|
||||||
}
|
}
|
||||||
if loops >= 0 {
|
if loops >= 0 {
|
||||||
@@ -378,14 +469,12 @@ fn handle_anime(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus.proxies()
|
proxy.set_builtin_animations(rog_anime::Animations {
|
||||||
.anime()
|
boot: builtins.boot,
|
||||||
.set_builtin_animations(rog_anime::Animations {
|
awake: builtins.awake,
|
||||||
boot: builtins.boot,
|
sleep: builtins.sleep,
|
||||||
awake: builtins.awake,
|
shutdown: builtins.shutdown,
|
||||||
sleep: builtins.sleep,
|
})?;
|
||||||
shutdown: builtins.shutdown,
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,16 +490,50 @@ fn verify_brightness(brightness: f32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_led_mode(
|
fn handle_slash(conn: &Connection, cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
if (cmd.brightness.is_none()
|
||||||
supported: &[String],
|
&& cmd.interval.is_none()
|
||||||
mode: &LedModeCommand,
|
&& cmd.slash_mode.is_none()
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
&& !cmd.list
|
||||||
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
&& !cmd.enable
|
||||||
println!("This laptop does not support power options");
|
&& !cmd.disable)
|
||||||
return Err(PlatformError::NotSupported.into());
|
|| cmd.help
|
||||||
|
{
|
||||||
|
println!("Missing arg or command\n\n{}", cmd.self_usage());
|
||||||
|
if let Some(lst) = cmd.self_command_list() {
|
||||||
|
println!("\n{}", lst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let proxy = SlashProxyBlocking::new(conn)?;
|
||||||
|
if cmd.enable {
|
||||||
|
proxy.set_enabled(true)?;
|
||||||
|
}
|
||||||
|
if cmd.disable {
|
||||||
|
proxy.set_enabled(false)?;
|
||||||
|
}
|
||||||
|
if let Some(brightness) = cmd.brightness {
|
||||||
|
proxy.set_brightness(brightness)?;
|
||||||
|
}
|
||||||
|
if let Some(interval) = cmd.interval {
|
||||||
|
proxy.set_interval(interval)?;
|
||||||
|
}
|
||||||
|
if let Some(slash_mode) = cmd.slash_mode {
|
||||||
|
proxy.set_slash_mode(slash_mode)?;
|
||||||
|
}
|
||||||
|
if cmd.list {
|
||||||
|
let res = SlashMode::list();
|
||||||
|
for p in &res {
|
||||||
|
println!("{:?}", p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_led_mode(
|
||||||
|
aura: &[AuraProxyBlocking],
|
||||||
|
mode: &LedModeCommand,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
||||||
if !mode.help {
|
if !mode.help {
|
||||||
println!("Missing arg or command\n");
|
println!("Missing arg or command\n");
|
||||||
@@ -420,8 +543,9 @@ fn handle_led_mode(
|
|||||||
|
|
||||||
if let Some(cmdlist) = LedModeCommand::command_list() {
|
if let Some(cmdlist) = LedModeCommand::command_list() {
|
||||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||||
|
// TODO: multiple rgb check
|
||||||
|
let modes = aura.first().unwrap().supported_basic_modes()?;
|
||||||
for command in commands.iter().filter(|command| {
|
for command in commands.iter().filter(|command| {
|
||||||
let modes = dbus.proxies().aura().supported_modes().unwrap();
|
|
||||||
for mode in &modes {
|
for mode in &modes {
|
||||||
if command
|
if command
|
||||||
.trim()
|
.trim()
|
||||||
@@ -449,71 +573,67 @@ fn handle_led_mode(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if mode.next_mode {
|
if mode.next_mode {
|
||||||
let mode = dbus.proxies().aura().led_mode()?;
|
for aura in aura {
|
||||||
let modes = dbus.proxies().aura().supported_modes()?;
|
let mode = aura.led_mode()?;
|
||||||
let mut pos = modes.iter().position(|m| *m == mode).unwrap() + 1;
|
let modes = aura.supported_basic_modes()?;
|
||||||
if pos >= modes.len() {
|
let mut pos = modes.iter().position(|m| *m == mode).unwrap() + 1;
|
||||||
pos = 0;
|
if pos >= modes.len() {
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
aura.set_led_mode(modes[pos])?;
|
||||||
}
|
}
|
||||||
dbus.proxies().aura().set_led_mode(modes[pos])?;
|
|
||||||
} else if mode.prev_mode {
|
} else if mode.prev_mode {
|
||||||
let mode = dbus.proxies().aura().led_mode()?;
|
for aura in aura {
|
||||||
let modes = dbus.proxies().aura().supported_modes()?;
|
let mode = aura.led_mode()?;
|
||||||
let mut pos = modes.iter().position(|m| *m == mode).unwrap();
|
let modes = aura.supported_basic_modes()?;
|
||||||
if pos == 0 {
|
let mut pos = modes.iter().position(|m| *m == mode).unwrap();
|
||||||
pos = modes.len() - 1;
|
if pos == 0 {
|
||||||
} else {
|
pos = modes.len() - 1;
|
||||||
pos -= 1;
|
} else {
|
||||||
|
pos -= 1;
|
||||||
|
}
|
||||||
|
aura.set_led_mode(modes[pos])?;
|
||||||
}
|
}
|
||||||
dbus.proxies().aura().set_led_mode(modes[pos])?;
|
|
||||||
} else if let Some(mode) = mode.command.as_ref() {
|
} else if let Some(mode) = mode.command.as_ref() {
|
||||||
if mode.help_requested() {
|
if mode.help_requested() {
|
||||||
println!("{}", mode.self_usage());
|
println!("{}", mode.self_usage());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
dbus.proxies()
|
for aura in aura {
|
||||||
.aura()
|
aura.set_led_mode_data(<AuraEffect>::from(mode))?;
|
||||||
.set_led_mode_data(<AuraEffect>::from(mode))?;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_led_power1(
|
fn handle_led_power1(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
aura: &[AuraProxyBlocking],
|
||||||
supported: &[String],
|
|
||||||
power: &LedPowerCommand1,
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
for aura in aura {
|
||||||
println!("This laptop does not support power options");
|
let dev_type = aura.device_type()?;
|
||||||
return Err(PlatformError::NotSupported.into());
|
if !dev_type.is_old_laptop() && !dev_type.is_tuf_laptop() {
|
||||||
}
|
println!("This option applies only to keyboards 2021+");
|
||||||
let dev_type = dbus.proxies().aura().device_type()?;
|
|
||||||
if !dev_type.is_old_style() && !dev_type.is_tuf_style() {
|
|
||||||
println!("This option applies only to keyboards 2021+");
|
|
||||||
}
|
|
||||||
|
|
||||||
if power.awake.is_none()
|
|
||||||
&& power.sleep.is_none()
|
|
||||||
&& power.boot.is_none()
|
|
||||||
&& power.keyboard.is_none()
|
|
||||||
&& power.lightbar.is_none()
|
|
||||||
{
|
|
||||||
if !power.help {
|
|
||||||
println!("Missing arg or command\n");
|
|
||||||
}
|
}
|
||||||
println!("{}\n", power.self_usage());
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if dev_type.is_old_style() {
|
if power.awake.is_none()
|
||||||
handle_led_power_1_do_1866(dbus, power)?;
|
&& power.sleep.is_none()
|
||||||
return Ok(());
|
&& power.boot.is_none()
|
||||||
}
|
&& !power.keyboard
|
||||||
|
&& !power.lightbar
|
||||||
|
{
|
||||||
|
if !power.help {
|
||||||
|
println!("Missing arg or command\n");
|
||||||
|
}
|
||||||
|
println!("{}\n", power.self_usage());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if dev_type.is_tuf_style() {
|
if dev_type.is_old_laptop() || dev_type.is_tuf_laptop() {
|
||||||
handle_led_power_1_do_tuf(dbus, power)?;
|
handle_led_power_1_do_1866(aura, power)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("These options are for keyboards of product ID 0x1866 or TUF only");
|
println!("These options are for keyboards of product ID 0x1866 or TUF only");
|
||||||
@@ -521,148 +641,102 @@ fn handle_led_power1(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_led_power_1_do_1866(
|
fn handle_led_power_1_do_1866(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
aura: &AuraProxyBlocking,
|
||||||
power: &LedPowerCommand1,
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut enabled: Vec<AuraDevRog1> = Vec::new();
|
let zone = if power.keyboard && power.lightbar {
|
||||||
let mut disabled: Vec<AuraDevRog1> = Vec::new();
|
PowerZones::KeyboardAndLightbar
|
||||||
|
} else if power.lightbar {
|
||||||
let mut check = |e: Option<bool>, a: AuraDevRog1| {
|
PowerZones::Lightbar
|
||||||
if let Some(arg) = e {
|
} else {
|
||||||
if arg {
|
PowerZones::Keyboard
|
||||||
enabled.push(a);
|
};
|
||||||
} else {
|
let states = LaptopAuraPower {
|
||||||
disabled.push(a);
|
states: vec![AuraPowerState {
|
||||||
}
|
zone,
|
||||||
}
|
boot: power.boot.unwrap_or_default(),
|
||||||
|
awake: power.awake.unwrap_or_default(),
|
||||||
|
sleep: power.sleep.unwrap_or_default(),
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
check(power.awake, AuraDevRog1::Awake);
|
aura.set_led_power(states)?;
|
||||||
check(power.boot, AuraDevRog1::Boot);
|
|
||||||
check(power.sleep, AuraDevRog1::Sleep);
|
|
||||||
check(power.keyboard, AuraDevRog1::Keyboard);
|
|
||||||
check(power.lightbar, AuraDevRog1::Lightbar);
|
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
|
||||||
old_rog: enabled,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
dbus.proxies().aura().set_led_power((data, true))?;
|
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
|
||||||
old_rog: disabled,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
dbus.proxies().aura().set_led_power((data, false))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_led_power_1_do_tuf(
|
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
|
||||||
power: &LedPowerCommand1,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut enabled: Vec<AuraDevTuf> = Vec::new();
|
|
||||||
let mut disabled: Vec<AuraDevTuf> = Vec::new();
|
|
||||||
|
|
||||||
let mut check = |e: Option<bool>, a: AuraDevTuf| {
|
|
||||||
if let Some(arg) = e {
|
|
||||||
if arg {
|
|
||||||
enabled.push(a);
|
|
||||||
} else {
|
|
||||||
disabled.push(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
check(power.awake, AuraDevTuf::Awake);
|
|
||||||
check(power.boot, AuraDevTuf::Boot);
|
|
||||||
check(power.sleep, AuraDevTuf::Sleep);
|
|
||||||
check(power.keyboard, AuraDevTuf::Keyboard);
|
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
|
||||||
tuf: enabled,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
dbus.proxies().aura().set_led_power((data, true))?;
|
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
|
||||||
tuf: disabled,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
dbus.proxies().aura().set_led_power((data, false))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_led_power2(
|
fn handle_led_power2(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
aura: &[AuraProxyBlocking],
|
||||||
supported: &[String],
|
|
||||||
power: &LedPowerCommand2,
|
power: &LedPowerCommand2,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
for aura in aura {
|
||||||
println!("This laptop does not support power options");
|
let dev_type = aura.device_type()?;
|
||||||
return Err(PlatformError::NotSupported.into());
|
if !dev_type.is_new_laptop() {
|
||||||
}
|
println!("This option applies only to keyboards 2021+");
|
||||||
let dev_type = dbus.proxies().aura().device_type()?;
|
continue;
|
||||||
if !dev_type.is_new_style() {
|
|
||||||
println!("This option applies only to keyboards 2021+");
|
|
||||||
}
|
|
||||||
|
|
||||||
if power.command().is_none() {
|
|
||||||
if !power.help {
|
|
||||||
println!("Missing arg or command\n");
|
|
||||||
}
|
}
|
||||||
println!("{}\n", power.self_usage());
|
|
||||||
println!("Commands available");
|
|
||||||
|
|
||||||
if let Some(cmdlist) = LedPowerCommand2::command_list() {
|
if power.command().is_none() {
|
||||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
if !power.help {
|
||||||
for command in &commands {
|
println!("Missing arg or command\n");
|
||||||
println!("{}", command);
|
|
||||||
}
|
}
|
||||||
}
|
println!("{}\n", power.self_usage());
|
||||||
|
println!("Commands available");
|
||||||
|
|
||||||
println!("\nHelp can also be requested on commands, e.g: boot --help");
|
if let Some(cmdlist) = LedPowerCommand2::command_list() {
|
||||||
return Ok(());
|
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||||
}
|
for command in &commands {
|
||||||
|
println!("{}", command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(pow) = power.command.as_ref() {
|
println!("\nHelp can also be requested on commands, e.g: boot --help");
|
||||||
if pow.help_requested() {
|
|
||||||
println!("{}", pow.self_usage());
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let set = |power: &mut KbAuraPowerState, set_to: &AuraPowerStates| {
|
if let Some(pow) = power.command.as_ref() {
|
||||||
power.boot = set_to.boot;
|
if pow.help_requested() {
|
||||||
power.awake = set_to.awake;
|
println!("{}", pow.self_usage());
|
||||||
power.sleep = set_to.sleep;
|
return Ok(());
|
||||||
power.shutdown = set_to.shutdown;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut enabled = dbus.proxies().aura().led_power()?;
|
|
||||||
if let Some(cmd) = &power.command {
|
|
||||||
match cmd {
|
|
||||||
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(&mut enabled.rog.keyboard, k),
|
|
||||||
aura_cli::SetAuraZoneEnabled::Logo(l) => set(&mut enabled.rog.logo, l),
|
|
||||||
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(&mut enabled.rog.lightbar, l),
|
|
||||||
aura_cli::SetAuraZoneEnabled::Lid(l) => set(&mut enabled.rog.lid, l),
|
|
||||||
aura_cli::SetAuraZoneEnabled::RearGlow(r) => set(&mut enabled.rog.rear_glow, r),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dbus.proxies().aura().set_led_power((enabled, true))?;
|
let mut states = aura.led_power()?;
|
||||||
|
let mut set = |zone: PowerZones, set_to: &AuraPowerStates| {
|
||||||
|
for state in states.states.iter_mut() {
|
||||||
|
if state.zone == zone {
|
||||||
|
state.boot = set_to.boot;
|
||||||
|
state.awake = set_to.awake;
|
||||||
|
state.sleep = set_to.sleep;
|
||||||
|
state.shutdown = set_to.shutdown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(cmd) = &power.command {
|
||||||
|
match cmd {
|
||||||
|
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(PowerZones::Keyboard, k),
|
||||||
|
aura_cli::SetAuraZoneEnabled::Logo(l) => set(PowerZones::Logo, l),
|
||||||
|
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.set_led_power(states)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_throttle_profile(
|
fn handle_throttle_profile(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
conn: &Connection,
|
||||||
supported: &[Properties],
|
supported: &[Properties],
|
||||||
cmd: &ProfileCommand,
|
cmd: &ProfileCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !supported.contains(&Properties::DgpuDisable) {
|
if !supported.contains(&Properties::ThrottlePolicy) {
|
||||||
println!("Profiles not supported by either this kernel or by the laptop.");
|
println!("Profiles not supported by either this kernel or by the laptop.");
|
||||||
return Err(ProfileError::NotSupported.into());
|
return Err(ProfileError::NotSupported.into());
|
||||||
}
|
}
|
||||||
@@ -678,20 +752,18 @@ fn handle_throttle_profile(
|
|||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let current = dbus.proxies().platform().throttle_thermal_policy()?;
|
|
||||||
|
let proxy = PlatformProxyBlocking::new(conn)?;
|
||||||
|
let current = proxy.throttle_thermal_policy()?;
|
||||||
|
|
||||||
if cmd.next {
|
if cmd.next {
|
||||||
dbus.proxies()
|
proxy.set_throttle_thermal_policy(current.next())?;
|
||||||
.platform()
|
|
||||||
.set_throttle_thermal_policy(current.next())?;
|
|
||||||
} else if let Some(profile) = cmd.profile_set {
|
} else if let Some(profile) = cmd.profile_set {
|
||||||
dbus.proxies()
|
proxy.set_throttle_thermal_policy(profile)?;
|
||||||
.platform()
|
|
||||||
.set_throttle_thermal_policy(profile)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.list {
|
if cmd.list {
|
||||||
let res = PlatformPolicy::list();
|
let res = ThrottlePolicy::list();
|
||||||
for p in &res {
|
for p in &res {
|
||||||
println!("{:?}", p);
|
println!("{:?}", p);
|
||||||
}
|
}
|
||||||
@@ -705,7 +777,7 @@ fn handle_throttle_profile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_fan_curve(
|
fn handle_fan_curve(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
conn: &Connection,
|
||||||
supported: &[String],
|
supported: &[String],
|
||||||
cmd: &FanCurveCommand,
|
cmd: &FanCurveCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@@ -736,36 +808,35 @@ fn handle_fan_curve(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let plat_proxy = PlatformProxyBlocking::new(conn)?;
|
||||||
|
let fan_proxy = FanCurvesProxyBlocking::new(conn)?;
|
||||||
if cmd.get_enabled {
|
if cmd.get_enabled {
|
||||||
let profile = dbus.proxies().platform().throttle_thermal_policy()?;
|
let profile = plat_proxy.throttle_thermal_policy()?;
|
||||||
let curves = dbus.proxies().fan_curves().fan_curve_data(profile)?;
|
let curves = fan_proxy.fan_curve_data(profile)?;
|
||||||
for curve in curves.iter() {
|
for curve in curves.iter() {
|
||||||
println!("{}", String::from(curve));
|
println!("{}", String::from(curve));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.default {
|
if cmd.default {
|
||||||
dbus.proxies().fan_curves().set_active_curve_to_defaults()?;
|
let active = plat_proxy.throttle_thermal_policy()?;
|
||||||
|
fan_proxy.set_curves_to_defaults(active)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(profile) = cmd.mod_profile {
|
if let Some(profile) = cmd.mod_profile {
|
||||||
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
|
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
|
||||||
let data = dbus.proxies().fan_curves().fan_curve_data(profile)?;
|
let data = fan_proxy.fan_curve_data(profile)?;
|
||||||
let data = toml::to_string(&data)?;
|
let data = toml::to_string(&data)?;
|
||||||
println!("\nFan curves for {:?}\n\n{}", profile, data);
|
println!("\nFan curves for {:?}\n\n{}", profile, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enabled) = cmd.enable_fan_curves {
|
if let Some(enabled) = cmd.enable_fan_curves {
|
||||||
dbus.proxies()
|
fan_proxy.set_fan_curves_enabled(profile, enabled)?;
|
||||||
.fan_curves()
|
|
||||||
.set_fan_curves_enabled(profile, enabled)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enabled) = cmd.enable_fan_curve {
|
if let Some(enabled) = cmd.enable_fan_curve {
|
||||||
if let Some(fan) = cmd.fan {
|
if let Some(fan) = cmd.fan {
|
||||||
dbus.proxies()
|
fan_proxy.set_profile_fan_curve_enabled(profile, fan, enabled)?;
|
||||||
.fan_curves()
|
|
||||||
.set_profile_fan_curve_enabled(profile, fan, enabled)?;
|
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
|
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
|
||||||
@@ -777,7 +848,7 @@ fn handle_fan_curve(
|
|||||||
if let Some(mut curve) = cmd.data.clone() {
|
if let Some(mut curve) = cmd.data.clone() {
|
||||||
let fan = cmd.fan.unwrap_or_default();
|
let fan = cmd.fan.unwrap_or_default();
|
||||||
curve.set_fan(fan);
|
curve.set_fan(fan);
|
||||||
dbus.proxies().fan_curves().set_fan_curve(profile, curve)?;
|
fan_proxy.set_fan_curve(profile, curve)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +856,7 @@ fn handle_fan_curve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_platform_properties(
|
fn handle_platform_properties(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
conn: &Connection,
|
||||||
supported: &[Properties],
|
supported: &[Properties],
|
||||||
cmd: &BiosCommand,
|
cmd: &BiosCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@@ -811,34 +882,34 @@ fn handle_platform_properties(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let proxy = PlatformProxyBlocking::new(conn)?;
|
||||||
|
|
||||||
if let Some(opt) = cmd.post_sound_set {
|
if let Some(opt) = cmd.post_sound_set {
|
||||||
dbus.proxies().platform().set_post_animation_sound(opt)?;
|
proxy.set_boot_sound(opt)?;
|
||||||
}
|
}
|
||||||
if cmd.post_sound_get {
|
if cmd.post_sound_get {
|
||||||
let res = dbus.proxies().platform().post_animation_sound()?;
|
let res = proxy.boot_sound()?;
|
||||||
println!("Bios POST sound on: {}", res);
|
println!("Bios POST sound on: {}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt) = cmd.gpu_mux_mode_set {
|
if let Some(opt) = cmd.gpu_mux_mode_set {
|
||||||
println!("Rebuilding initrd to include drivers");
|
println!("Rebuilding initrd to include drivers");
|
||||||
dbus.proxies()
|
proxy.set_gpu_mux_mode(GpuMode::from_mux(opt))?;
|
||||||
.platform()
|
|
||||||
.set_gpu_mux_mode(GpuMode::from_mux(opt))?;
|
|
||||||
println!(
|
println!(
|
||||||
"The mode change is not active until you reboot, on boot the bios will make the \
|
"The mode change is not active until you reboot, on boot the bios will make the \
|
||||||
required change"
|
required change"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if cmd.gpu_mux_mode_get {
|
if cmd.gpu_mux_mode_get {
|
||||||
let res = dbus.proxies().platform().gpu_mux_mode()?;
|
let res = proxy.gpu_mux_mode()?;
|
||||||
println!("Bios GPU MUX: {:?}", res);
|
println!("Bios GPU MUX: {:?}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt) = cmd.panel_overdrive_set {
|
if let Some(opt) = cmd.panel_overdrive_set {
|
||||||
dbus.proxies().platform().set_panel_od(opt)?;
|
proxy.set_panel_od(opt)?;
|
||||||
}
|
}
|
||||||
if cmd.panel_overdrive_get {
|
if cmd.panel_overdrive_get {
|
||||||
let res = dbus.proxies().platform().panel_od()?;
|
let res = proxy.panel_od()?;
|
||||||
println!("Panel overdrive on: {}", res);
|
println!("Panel overdrive on: {}", res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
use gumdrop::Options;
|
||||||
|
use rog_slash::SlashMode;
|
||||||
|
|
||||||
|
#[derive(Options)]
|
||||||
|
pub struct SlashCommand {
|
||||||
|
#[options(help = "print help message")]
|
||||||
|
pub help: bool,
|
||||||
|
#[options(help = "Enable the Slash Ledbar")]
|
||||||
|
pub enable: bool,
|
||||||
|
#[options(help = "Ddisable the Slash Ledbar")]
|
||||||
|
pub disable: bool,
|
||||||
|
#[options(meta = "", help = "Set brightness value <0-255>")]
|
||||||
|
pub brightness: Option<u8>,
|
||||||
|
#[options(meta = "", help = "Set interval value <0-255>")]
|
||||||
|
pub interval: Option<u8>,
|
||||||
|
#[options(help = "Set SlashMode (so 'list' for all options)")]
|
||||||
|
pub slash_mode: Option<SlashMode>,
|
||||||
|
#[options(help = "list available animations")]
|
||||||
|
pub list: bool,
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_anime::{ActionLoader, AnimTime, AnimeType, Fade, Sequences as AnimeSequences, Vec2};
|
use rog_anime::{ActionLoader, AnimTime, AnimeType, Fade, Sequences as AnimeSequences, Vec2};
|
||||||
use rog_aura::advanced::LedCode;
|
|
||||||
use rog_aura::effects::{AdvancedEffects as AuraSequences, Breathe, DoomFlicker, Effect, Static};
|
use rog_aura::effects::{AdvancedEffects as AuraSequences, Breathe, DoomFlicker, Effect, Static};
|
||||||
|
use rog_aura::keyboard::LedCode;
|
||||||
use rog_aura::{Colour, Speed};
|
use rog_aura::{Colour, Speed};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use std::time::{Duration, Instant};
|
|||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use rog_anime::error::AnimeError;
|
use rog_anime::error::AnimeError;
|
||||||
use rog_anime::{ActionData, ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
use rog_anime::{ActionData, ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use zbus::dbus_interface;
|
use zbus::interface;
|
||||||
use zbus::zvariant::{ObjectPath, Type};
|
use zbus::zvariant::{ObjectPath, Type};
|
||||||
|
|
||||||
use crate::config::ConfigAnime;
|
use crate::config::ConfigAnime;
|
||||||
@@ -61,14 +61,14 @@ pub enum TimeType {
|
|||||||
/// thread and a zbus server behind `Arc<Mutex<T>>`
|
/// thread and a zbus server behind `Arc<Mutex<T>>`
|
||||||
pub struct CtrlAnimeInner<'a> {
|
pub struct CtrlAnimeInner<'a> {
|
||||||
sequences: Sequences,
|
sequences: Sequences,
|
||||||
client: RogDbusClientBlocking<'a>,
|
client: AnimeProxyBlocking<'a>,
|
||||||
do_early_return: Arc<AtomicBool>,
|
do_early_return: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CtrlAnimeInner<'static> {
|
impl<'a> CtrlAnimeInner<'static> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
sequences: Sequences,
|
sequences: Sequences,
|
||||||
client: RogDbusClientBlocking<'static>,
|
client: AnimeProxyBlocking<'static>,
|
||||||
do_early_return: Arc<AtomicBool>,
|
do_early_return: Arc<AtomicBool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -93,19 +93,13 @@ impl<'a> CtrlAnimeInner<'static> {
|
|||||||
return Ok(true); // Do safe exit
|
return Ok(true); // Do safe exit
|
||||||
}
|
}
|
||||||
self.client
|
self.client
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(output)
|
.write(output)
|
||||||
.map_err(|e| AnimeError::Dbus(format!("{}", e)))
|
.map_err(|e| AnimeError::Dbus(format!("{}", e)))
|
||||||
.map(|_| false)
|
.map(|_| false)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ActionData::Image(image) => {
|
ActionData::Image(image) => {
|
||||||
self.client
|
self.client.write(image.as_ref().clone()).ok();
|
||||||
.proxies()
|
|
||||||
.anime()
|
|
||||||
.write(image.as_ref().clone())
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
ActionData::Pause(duration) => {
|
ActionData::Pause(duration) => {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@@ -132,7 +126,7 @@ impl<'a> CtrlAnimeInner<'static> {
|
|||||||
|
|
||||||
pub struct CtrlAnime<'a> {
|
pub struct CtrlAnime<'a> {
|
||||||
config: Arc<Mutex<ConfigAnime>>,
|
config: Arc<Mutex<ConfigAnime>>,
|
||||||
client: RogDbusClientBlocking<'a>,
|
client: AnimeProxyBlocking<'a>,
|
||||||
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
||||||
/// Must be the same Atomic as in CtrlAnimeInner
|
/// Must be the same Atomic as in CtrlAnimeInner
|
||||||
inner_early_return: Arc<AtomicBool>,
|
inner_early_return: Arc<AtomicBool>,
|
||||||
@@ -142,7 +136,7 @@ impl CtrlAnime<'static> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
config: Arc<Mutex<ConfigAnime>>,
|
config: Arc<Mutex<ConfigAnime>>,
|
||||||
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
||||||
client: RogDbusClientBlocking<'static>,
|
client: AnimeProxyBlocking<'static>,
|
||||||
inner_early_return: Arc<AtomicBool>,
|
inner_early_return: Arc<AtomicBool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(CtrlAnime {
|
Ok(CtrlAnime {
|
||||||
@@ -175,7 +169,7 @@ impl CtrlAnime<'static> {
|
|||||||
// - Do actions
|
// - Do actions
|
||||||
// - Write config if required
|
// - Write config if required
|
||||||
// - Unset inner_early_return
|
// - Unset inner_early_return
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[interface(name = "org.asuslinux.Daemon")]
|
||||||
impl CtrlAnime<'static> {
|
impl CtrlAnime<'static> {
|
||||||
pub fn insert_asus_gif(
|
pub fn insert_asus_gif(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -356,13 +350,13 @@ impl CtrlAnime<'static> {
|
|||||||
pub fn set_state(&mut self, on: bool) -> zbus::fdo::Result<()> {
|
pub fn set_state(&mut self, on: bool) -> zbus::fdo::Result<()> {
|
||||||
// Operations here need to be in specific order
|
// Operations here need to be in specific order
|
||||||
if on {
|
if on {
|
||||||
self.client.proxies().anime().set_enable_display(on).ok();
|
self.client.set_enable_display(on).ok();
|
||||||
// Let the inner loop run
|
// Let the inner loop run
|
||||||
self.inner_early_return.store(false, Ordering::SeqCst);
|
self.inner_early_return.store(false, Ordering::SeqCst);
|
||||||
} else {
|
} else {
|
||||||
// Must make the inner run loop return early
|
// Must make the inner run loop return early
|
||||||
self.inner_early_return.store(true, Ordering::SeqCst);
|
self.inner_early_return.store(true, Ordering::SeqCst);
|
||||||
self.client.proxies().anime().set_enable_display(on).ok();
|
self.client.set_enable_display(on).ok();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-22
@@ -7,9 +7,12 @@ use asusd_user::config::*;
|
|||||||
use asusd_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
|
use asusd_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::layouts::KeyLayout;
|
use rog_aura::keyboard::KeyLayout;
|
||||||
use rog_dbus::{RogDbusClientBlocking, DBUS_NAME};
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
|
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||||
|
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||||
|
use rog_dbus::DBUS_NAME;
|
||||||
use smol::Executor;
|
use smol::Executor;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
@@ -32,10 +35,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||||
println!("rog-platform v{}", rog_platform::VERSION);
|
println!("rog-platform v{}", rog_platform::VERSION);
|
||||||
|
|
||||||
let (client, _) = RogDbusClientBlocking::new()?;
|
let conn = zbus::blocking::Connection::system().unwrap();
|
||||||
let supported = client
|
let platform_proxy = PlatformProxyBlocking::new(&conn).unwrap();
|
||||||
.proxies()
|
|
||||||
.platform()
|
let supported = platform_proxy
|
||||||
.supported_interfaces()
|
.supported_interfaces()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.contains(&"Anime".to_string());
|
.contains(&"Anime".to_string());
|
||||||
@@ -51,6 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let anime = anime_config.create(anime_type)?;
|
let anime = anime_config.create(anime_type)?;
|
||||||
let anime_config = Arc::new(Mutex::new(anime_config));
|
let anime_config = Arc::new(Mutex::new(anime_config));
|
||||||
|
|
||||||
|
let anime_proxy_blocking = AnimeProxyBlocking::new(&conn).unwrap();
|
||||||
executor
|
executor
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
// Create server
|
// Create server
|
||||||
@@ -59,12 +63,21 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Inner behind mutex required for thread safety
|
// Inner behind mutex required for thread safety
|
||||||
let inner = Arc::new(Mutex::new(
|
let inner = Arc::new(Mutex::new(
|
||||||
CtrlAnimeInner::new(anime, client, early_return.clone()).unwrap(),
|
CtrlAnimeInner::new(
|
||||||
|
anime,
|
||||||
|
anime_proxy_blocking.clone(),
|
||||||
|
early_return.clone(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
));
|
));
|
||||||
// Need new client object for dbus control part
|
// Need new client object for dbus control part
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let anime_control = CtrlAnime::new(
|
||||||
let anime_control =
|
anime_config,
|
||||||
CtrlAnime::new(anime_config, inner.clone(), client, early_return).unwrap();
|
inner.clone(),
|
||||||
|
anime_proxy_blocking,
|
||||||
|
early_return,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
anime_control.add_to_server(&mut connection).await;
|
anime_control.add_to_server(&mut connection).await;
|
||||||
loop {
|
loop {
|
||||||
if let Ok(inner) = inner.clone().try_lock() {
|
if let Ok(inner) = inner.clone().try_lock() {
|
||||||
@@ -81,7 +94,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let mut aura_config = ConfigAura::new().set_name(cfg).load();
|
let mut aura_config = ConfigAura::new().set_name(cfg).load();
|
||||||
// let baord_name = std::fs::read_to_string(BOARD_NAME)?;
|
// let baord_name = std::fs::read_to_string(BOARD_NAME)?;
|
||||||
|
|
||||||
let led_support = LaptopLedData::get_data();
|
let led_support = LedSupportData::get_data("");
|
||||||
|
|
||||||
let layout = KeyLayout::find_layout(led_support, PathBuf::from(DATA_DIR))
|
let layout = KeyLayout::find_layout(led_support, PathBuf::from(DATA_DIR))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
@@ -89,22 +102,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
})
|
})
|
||||||
.unwrap_or_else(|_| KeyLayout::default_layout());
|
.unwrap_or_else(|_| KeyLayout::default_layout());
|
||||||
|
|
||||||
|
let aura_proxy_blocking = AuraProxyBlocking::new(&conn).unwrap();
|
||||||
executor
|
executor
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
// Create server
|
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
|
||||||
// let connection = Connection::session().await.unwrap();
|
|
||||||
// connection.request_name(DBUS_NAME).await.unwrap();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
aura_config.aura.next_state(&layout);
|
aura_config.aura.next_state(&layout);
|
||||||
let packets = aura_config.aura.create_packets();
|
let packets = aura_config.aura.create_packets();
|
||||||
|
|
||||||
client
|
aura_proxy_blocking.direct_addressing_raw(packets).unwrap();
|
||||||
.proxies()
|
|
||||||
.aura()
|
|
||||||
.direct_addressing_raw(packets)
|
|
||||||
.unwrap();
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(33));
|
std::thread::sleep(std::time::Duration::from_millis(33));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
use zbus::dbus_proxy;
|
use zbus::proxy;
|
||||||
|
|
||||||
#[dbus_proxy(
|
#[proxy(
|
||||||
interface = "org.asuslinux.Daemon",
|
interface = "org.asuslinux.Daemon",
|
||||||
default_path = "/org/asuslinux/Anime"
|
default_path = "/org/asuslinux/Anime"
|
||||||
)]
|
)]
|
||||||
|
|||||||
+5
-2
@@ -16,15 +16,18 @@ path = "src/daemon.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
config-traits = { path = "../config-traits" }
|
config-traits = { path = "../config-traits" }
|
||||||
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
||||||
|
rog_slash = { path = "../rog-slash", features = ["dbus"] }
|
||||||
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
dmi_id = { path = "../dmi-id" }
|
dmi_id = { path = "../dmi-id" }
|
||||||
futures-lite = "*"
|
futures-lite = "*"
|
||||||
udev.workspace = true
|
udev.workspace = true
|
||||||
|
inotify.workspace = true
|
||||||
|
|
||||||
async-trait.workspace = true
|
mio.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
# console-subscriber = "0.2.0"
|
||||||
|
|
||||||
# cli and logging
|
# cli and logging
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
@@ -42,4 +45,4 @@ concat-idents.workspace = true
|
|||||||
systemd-zbus = "*"
|
systemd-zbus = "*"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cargo-husky.workspace = true
|
cargo-husky.workspace = true
|
||||||
|
|||||||
+179
-51
@@ -1,11 +1,108 @@
|
|||||||
use config_traits::{StdConfig, StdConfigLoad2};
|
use config_traits::{StdConfig, StdConfigLoad3};
|
||||||
use rog_platform::platform::PlatformPolicy;
|
use rog_platform::cpu::CPUEPP;
|
||||||
|
use rog_platform::platform::ThrottlePolicy;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "asusd.ron";
|
const CONFIG_FILE: &str = "asusd.ron";
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug)]
|
#[derive(Deserialize, Serialize, Debug, PartialEq, PartialOrd)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
/// Save charge limit for restoring on boot/resume
|
||||||
|
pub charge_control_end_threshold: u8,
|
||||||
|
pub panel_od: bool,
|
||||||
|
pub boot_sound: bool,
|
||||||
|
pub mini_led_mode: bool,
|
||||||
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
|
/// An optional command/script to run when power is changed to AC
|
||||||
|
pub ac_command: String,
|
||||||
|
/// An optional command/script to run when power is changed to battery
|
||||||
|
pub bat_command: String,
|
||||||
|
/// Set true if energy_performance_preference should be set if the
|
||||||
|
/// throttle/platform profile is changed
|
||||||
|
pub throttle_policy_linked_epp: bool,
|
||||||
|
/// Which throttle/profile to use on battery power
|
||||||
|
pub throttle_policy_on_battery: ThrottlePolicy,
|
||||||
|
/// Which throttle/profile to use on AC power
|
||||||
|
pub throttle_policy_on_ac: ThrottlePolicy,
|
||||||
|
/// The energy_performance_preference for this throttle/platform profile
|
||||||
|
pub throttle_quiet_epp: CPUEPP,
|
||||||
|
/// The energy_performance_preference for this throttle/platform profile
|
||||||
|
pub throttle_balanced_epp: CPUEPP,
|
||||||
|
/// The energy_performance_preference for this throttle/platform profile
|
||||||
|
pub throttle_performance_epp: CPUEPP,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub ppt_pl1_spl: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub ppt_pl2_sppt: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub ppt_fppt: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub ppt_apu_sppt: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub ppt_platform_sppt: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub nv_dynamic_boost: Option<u8>,
|
||||||
|
/// Defaults to `None` if not supported
|
||||||
|
pub nv_temp_target: Option<u8>,
|
||||||
|
/// Temporary state for AC/Batt
|
||||||
|
#[serde(skip)]
|
||||||
|
pub last_power_plugged: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
charge_control_end_threshold: 100,
|
||||||
|
panel_od: false,
|
||||||
|
boot_sound: false,
|
||||||
|
mini_led_mode: false,
|
||||||
|
disable_nvidia_powerd_on_battery: true,
|
||||||
|
ac_command: Default::default(),
|
||||||
|
bat_command: Default::default(),
|
||||||
|
throttle_policy_linked_epp: true,
|
||||||
|
throttle_policy_on_battery: ThrottlePolicy::Quiet,
|
||||||
|
throttle_policy_on_ac: ThrottlePolicy::Performance,
|
||||||
|
throttle_quiet_epp: CPUEPP::Power,
|
||||||
|
throttle_balanced_epp: CPUEPP::BalancePower,
|
||||||
|
throttle_performance_epp: CPUEPP::Performance,
|
||||||
|
ppt_pl1_spl: Default::default(),
|
||||||
|
ppt_pl2_sppt: Default::default(),
|
||||||
|
ppt_fppt: Default::default(),
|
||||||
|
ppt_apu_sppt: Default::default(),
|
||||||
|
ppt_platform_sppt: Default::default(),
|
||||||
|
nv_dynamic_boost: Default::default(),
|
||||||
|
nv_temp_target: Default::default(),
|
||||||
|
last_power_plugged: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfig for Config {
|
||||||
|
fn new() -> Self {
|
||||||
|
Config {
|
||||||
|
charge_control_end_threshold: 100,
|
||||||
|
disable_nvidia_powerd_on_battery: true,
|
||||||
|
throttle_policy_on_battery: ThrottlePolicy::Quiet,
|
||||||
|
throttle_policy_on_ac: ThrottlePolicy::Performance,
|
||||||
|
ac_command: String::new(),
|
||||||
|
bat_command: String::new(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> String {
|
||||||
|
CONFIG_FILE.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_dir() -> std::path::PathBuf {
|
||||||
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfigLoad3<Config472, Config506, Config507> for Config {}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Config507 {
|
||||||
/// Save charge limit for restoring on boot
|
/// Save charge limit for restoring on boot
|
||||||
pub charge_control_end_threshold: u8,
|
pub charge_control_end_threshold: u8,
|
||||||
pub panel_od: bool,
|
pub panel_od: bool,
|
||||||
@@ -13,11 +110,9 @@ pub struct Config {
|
|||||||
pub disable_nvidia_powerd_on_battery: bool,
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
pub ac_command: String,
|
pub ac_command: String,
|
||||||
pub bat_command: String,
|
pub bat_command: String,
|
||||||
/// Restored on boot as well as when power is plugged
|
pub platform_policy_linked_epp: bool,
|
||||||
#[serde(skip)]
|
pub platform_policy_on_battery: ThrottlePolicy,
|
||||||
pub platform_policy_to_restore: PlatformPolicy,
|
pub platform_policy_on_ac: ThrottlePolicy,
|
||||||
pub platform_policy_on_battery: PlatformPolicy,
|
|
||||||
pub platform_policy_on_ac: PlatformPolicy,
|
|
||||||
//
|
//
|
||||||
pub ppt_pl1_spl: Option<u8>,
|
pub ppt_pl1_spl: Option<u8>,
|
||||||
pub ppt_pl2_sppt: Option<u8>,
|
pub ppt_pl2_sppt: Option<u8>,
|
||||||
@@ -28,31 +123,87 @@ pub struct Config {
|
|||||||
pub nv_temp_target: Option<u8>,
|
pub nv_temp_target: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for Config {
|
impl From<Config507> for Config {
|
||||||
fn new() -> Self {
|
fn from(c: Config507) -> Self {
|
||||||
Config {
|
Self {
|
||||||
charge_control_end_threshold: 100,
|
charge_control_end_threshold: c.charge_control_end_threshold,
|
||||||
disable_nvidia_powerd_on_battery: true,
|
panel_od: c.panel_od,
|
||||||
platform_policy_on_battery: PlatformPolicy::Quiet,
|
boot_sound: false,
|
||||||
platform_policy_on_ac: PlatformPolicy::Performance,
|
disable_nvidia_powerd_on_battery: c.disable_nvidia_powerd_on_battery,
|
||||||
ac_command: String::new(),
|
ac_command: c.ac_command,
|
||||||
bat_command: String::new(),
|
bat_command: c.bat_command,
|
||||||
..Default::default()
|
mini_led_mode: c.mini_led_mode,
|
||||||
|
throttle_policy_linked_epp: true,
|
||||||
|
throttle_policy_on_battery: c.platform_policy_on_battery,
|
||||||
|
throttle_policy_on_ac: c.platform_policy_on_ac,
|
||||||
|
throttle_quiet_epp: CPUEPP::Power,
|
||||||
|
throttle_balanced_epp: CPUEPP::BalancePower,
|
||||||
|
throttle_performance_epp: CPUEPP::Performance,
|
||||||
|
ppt_pl1_spl: c.ppt_pl1_spl,
|
||||||
|
ppt_pl2_sppt: c.ppt_pl2_sppt,
|
||||||
|
ppt_fppt: c.ppt_fppt,
|
||||||
|
ppt_apu_sppt: c.ppt_apu_sppt,
|
||||||
|
ppt_platform_sppt: c.ppt_platform_sppt,
|
||||||
|
nv_dynamic_boost: c.nv_dynamic_boost,
|
||||||
|
nv_temp_target: c.nv_temp_target,
|
||||||
|
last_power_plugged: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
|
||||||
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
|
||||||
CONFIG_FILE.to_owned()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad2<Config462, Config472> for Config {}
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Config506 {
|
||||||
|
/// Save charge limit for restoring on boot
|
||||||
|
pub charge_control_end_threshold: u8,
|
||||||
|
pub panel_od: bool,
|
||||||
|
pub mini_led_mode: bool,
|
||||||
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
|
pub ac_command: String,
|
||||||
|
pub bat_command: String,
|
||||||
|
/// Restored on boot as well as when power is plugged
|
||||||
|
#[serde(skip)]
|
||||||
|
pub platform_policy_to_restore: ThrottlePolicy,
|
||||||
|
pub platform_policy_on_battery: ThrottlePolicy,
|
||||||
|
pub platform_policy_on_ac: ThrottlePolicy,
|
||||||
|
//
|
||||||
|
pub ppt_pl1_spl: Option<u8>,
|
||||||
|
pub ppt_pl2_sppt: Option<u8>,
|
||||||
|
pub ppt_fppt: Option<u8>,
|
||||||
|
pub ppt_apu_sppt: Option<u8>,
|
||||||
|
pub ppt_platform_sppt: Option<u8>,
|
||||||
|
pub nv_dynamic_boost: Option<u8>,
|
||||||
|
pub nv_temp_target: Option<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug)]
|
impl From<Config506> for Config {
|
||||||
|
fn from(c: Config506) -> Self {
|
||||||
|
Self {
|
||||||
|
charge_control_end_threshold: c.charge_control_end_threshold,
|
||||||
|
panel_od: c.panel_od,
|
||||||
|
boot_sound: false,
|
||||||
|
disable_nvidia_powerd_on_battery: c.disable_nvidia_powerd_on_battery,
|
||||||
|
ac_command: c.ac_command,
|
||||||
|
bat_command: c.bat_command,
|
||||||
|
mini_led_mode: c.mini_led_mode,
|
||||||
|
throttle_policy_linked_epp: true,
|
||||||
|
throttle_policy_on_battery: c.platform_policy_on_battery,
|
||||||
|
throttle_policy_on_ac: c.platform_policy_on_ac,
|
||||||
|
throttle_quiet_epp: CPUEPP::Power,
|
||||||
|
throttle_balanced_epp: CPUEPP::BalancePower,
|
||||||
|
throttle_performance_epp: CPUEPP::Performance,
|
||||||
|
ppt_pl1_spl: c.ppt_pl1_spl,
|
||||||
|
ppt_pl2_sppt: c.ppt_pl2_sppt,
|
||||||
|
ppt_fppt: c.ppt_fppt,
|
||||||
|
ppt_apu_sppt: c.ppt_apu_sppt,
|
||||||
|
ppt_platform_sppt: c.ppt_platform_sppt,
|
||||||
|
nv_dynamic_boost: c.nv_dynamic_boost,
|
||||||
|
nv_temp_target: c.nv_temp_target,
|
||||||
|
last_power_plugged: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Config472 {
|
pub struct Config472 {
|
||||||
/// Save charge limit for restoring on boot
|
/// Save charge limit for restoring on boot
|
||||||
pub bat_charge_limit: u8,
|
pub bat_charge_limit: u8,
|
||||||
@@ -75,26 +226,3 @@ impl From<Config472> for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub struct Config462 {
|
|
||||||
/// Save charge limit for restoring on boot
|
|
||||||
pub bat_charge_limit: u8,
|
|
||||||
pub panel_od: bool,
|
|
||||||
pub disable_nvidia_powerd_on_battery: bool,
|
|
||||||
pub ac_command: String,
|
|
||||||
pub bat_command: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Config462> for Config {
|
|
||||||
fn from(c: Config462) -> Self {
|
|
||||||
Self {
|
|
||||||
charge_control_end_threshold: c.bat_charge_limit,
|
|
||||||
panel_od: c.panel_od,
|
|
||||||
disable_nvidia_powerd_on_battery: true,
|
|
||||||
ac_command: String::new(),
|
|
||||||
bat_command: String::new(),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl AnimeConfigCached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Config for base system actions for the anime display
|
/// Config for base system actions for the anime display
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
pub struct AnimeConfig {
|
pub struct AnimeConfig {
|
||||||
pub model_override: Option<AnimeType>,
|
pub model_override: Option<AnimeType>,
|
||||||
pub system: Vec<ActionLoader>,
|
pub system: Vec<ActionLoader>,
|
||||||
@@ -150,13 +150,13 @@ impl StdConfig for AnimeConfig {
|
|||||||
Self::create_default()
|
Self::create_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
|
||||||
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
fn file_name(&self) -> String {
|
||||||
CONFIG_FILE.to_owned()
|
CONFIG_FILE.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn config_dir() -> std::path::PathBuf {
|
||||||
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV472> for AnimeConfig {}
|
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV472> for AnimeConfig {}
|
||||||
|
|||||||
+13
-11
@@ -66,26 +66,28 @@ impl CtrlAnime {
|
|||||||
let usb = USBRaw::new(0x193b).ok();
|
let usb = USBRaw::new(0x193b).ok();
|
||||||
let hid = HidRaw::new("193b").ok();
|
let hid = HidRaw::new("193b").ok();
|
||||||
let node = if usb.is_some() {
|
let node = if usb.is_some() {
|
||||||
|
info!("Anime using the USB interface");
|
||||||
unsafe { Node::Usb(usb.unwrap_unchecked()) }
|
unsafe { Node::Usb(usb.unwrap_unchecked()) }
|
||||||
} else if hid.is_some() {
|
} else if hid.is_some() {
|
||||||
|
info!("Anime using the HID interface");
|
||||||
unsafe { Node::Hid(hid.unwrap_unchecked()) }
|
unsafe { Node::Hid(hid.unwrap_unchecked()) }
|
||||||
} else {
|
} else {
|
||||||
return Err(RogError::Anime(AnimeError::NoDevice));
|
return Err(RogError::Anime(AnimeError::NoDevice));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: something better to set wakeups disabled
|
// TODO: something better to set wakeups disabled
|
||||||
if matches!(node, Node::Usb(_)) {
|
// if matches!(node, Node::Usb(_)) {
|
||||||
if let Ok(mut enumerator) = udev::Enumerator::new() {
|
// if let Ok(mut enumerator) = udev::Enumerator::new() {
|
||||||
enumerator.match_subsystem("usb").ok();
|
// enumerator.match_subsystem("usb").ok();
|
||||||
enumerator.match_attribute("idProduct", "193b").ok();
|
// enumerator.match_attribute("idProduct", "193b").ok();
|
||||||
|
|
||||||
if let Ok(mut enumer) = enumerator.scan_devices() {
|
// if let Ok(mut enumer) = enumerator.scan_devices() {
|
||||||
if let Some(mut dev) = enumer.next() {
|
// if let Some(mut dev) = enumer.next() {
|
||||||
dev.set_attribute_value("power/wakeup", "disabled").ok();
|
// dev.set_attribute_value("power/wakeup", "disabled").ok();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
let mut anime_type = get_anime_type()?;
|
let mut anime_type = get_anime_type()?;
|
||||||
if let AnimeType::Unknown = anime_type {
|
if let AnimeType::Unknown = anime_type {
|
||||||
|
|||||||
+205
-115
@@ -1,7 +1,6 @@
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
@@ -11,13 +10,14 @@ use rog_anime::usb::{
|
|||||||
};
|
};
|
||||||
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::{dbus_interface, CacheProperties, Connection, SignalContext};
|
use zbus::{interface, CacheProperties, Connection, SignalContext};
|
||||||
|
|
||||||
|
use super::config::AnimeConfig;
|
||||||
use super::CtrlAnime;
|
use super::CtrlAnime;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
|
|
||||||
pub const ANIME_ZBUS_NAME: &str = "Anime";
|
pub const ANIME_ZBUS_NAME: &str = "Anime";
|
||||||
pub const ANIME_ZBUS_PATH: &str = "/org/asuslinux/Anime";
|
pub const ANIME_ZBUS_PATH: &str = "/org/asuslinux";
|
||||||
|
|
||||||
async fn get_logind_manager<'a>() -> ManagerProxy<'a> {
|
async fn get_logind_manager<'a>() -> ManagerProxy<'a> {
|
||||||
let connection = Connection::system()
|
let connection = Connection::system()
|
||||||
@@ -35,7 +35,6 @@ async fn get_logind_manager<'a>() -> ManagerProxy<'a> {
|
|||||||
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
/// The struct with the main dbus methods requires this trait
|
/// The struct with the main dbus methods requires this trait
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for CtrlAnimeZbus {
|
impl crate::ZbusRun for CtrlAnimeZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, ANIME_ZBUS_PATH, server).await;
|
Self::add_to_server_helper(self, ANIME_ZBUS_PATH, server).await;
|
||||||
@@ -45,50 +44,61 @@ impl crate::ZbusRun for CtrlAnimeZbus {
|
|||||||
// None of these calls can be guarnateed to succeed unless we loop until okay
|
// None of these calls can be guarnateed to succeed unless we loop until okay
|
||||||
// If the try_lock *does* succeed then any other thread trying to lock will not
|
// If the try_lock *does* succeed then any other thread trying to lock will not
|
||||||
// grab it until we finish.
|
// grab it until we finish.
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[interface(name = "org.asuslinux.Anime")]
|
||||||
impl CtrlAnimeZbus {
|
impl CtrlAnimeZbus {
|
||||||
/// Writes a data stream of length. Will force system thread to exit until
|
/// Writes a data stream of length. Will force system thread to exit until
|
||||||
/// it is restarted
|
/// it is restarted
|
||||||
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
||||||
let lock = self.0.lock().await;
|
self.0
|
||||||
lock.thread_exit.store(true, Ordering::SeqCst);
|
.lock()
|
||||||
lock.write_data_buffer(input).map_err(|err| {
|
.await
|
||||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
.thread_exit
|
||||||
err
|
.store(true, Ordering::SeqCst);
|
||||||
})?;
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.write_data_buffer(input)
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set base brightness level
|
/// Set base brightness level
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn brightness(&self) -> Brightness {
|
async fn brightness(&self) -> Brightness {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.display_brightness
|
||||||
lock.config.display_brightness
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set base brightness level
|
/// Set base brightness level
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_brightness(&self, brightness: Brightness) {
|
async fn set_brightness(&self, brightness: Brightness) {
|
||||||
let mut lock = self.0.lock().await;
|
self.0
|
||||||
lock.node
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_brightness(brightness))
|
.write_bytes(&pkt_set_brightness(brightness))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::set_brightness {}", err);
|
warn!("ctrl_anime::set_brightness {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.node
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(brightness != Brightness::Off))
|
.write_bytes(&pkt_set_enable_display(brightness != Brightness::Off))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::set_brightness {}", err);
|
warn!("ctrl_anime::set_brightness {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
lock.config.display_enabled = brightness != Brightness::Off;
|
self.0.lock().await.config.display_enabled = brightness != Brightness::Off;
|
||||||
lock.config.display_brightness = brightness;
|
self.0.lock().await.config.display_brightness = brightness;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn builtins_enabled(&self) -> bool {
|
async fn builtins_enabled(&self) -> bool {
|
||||||
let lock = self.0.lock().await;
|
let lock = self.0.lock().await;
|
||||||
lock.config.builtin_anims_enabled
|
lock.config.builtin_anims_enabled
|
||||||
@@ -96,22 +106,29 @@ impl CtrlAnimeZbus {
|
|||||||
|
|
||||||
/// Enable the builtin animations or not. This is quivalent to "Powersave
|
/// Enable the builtin animations or not. This is quivalent to "Powersave
|
||||||
/// animations" in Armory crate
|
/// animations" in Armory crate
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_builtins_enabled(&self, enabled: bool) {
|
async fn set_builtins_enabled(&self, enabled: bool) {
|
||||||
let mut lock = self.0.lock().await;
|
let brightness = self.0.lock().await.config.display_brightness;
|
||||||
lock.node
|
self.0
|
||||||
.set_builtins_enabled(enabled, lock.config.display_brightness)
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
|
.set_builtins_enabled(enabled, brightness)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
if !enabled {
|
if !enabled {
|
||||||
let data = vec![255u8; lock.anime_type.data_length()];
|
let anime_type = self.0.lock().await.anime_type;
|
||||||
if let Ok(tmp) = AnimeDataBuffer::from_vec(lock.anime_type, data).map_err(|err| {
|
let data = vec![255u8; anime_type.data_length()];
|
||||||
|
if let Ok(tmp) = AnimeDataBuffer::from_vec(anime_type, data).map_err(|err| {
|
||||||
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
}) {
|
}) {
|
||||||
lock.node
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(tmp.data())
|
.write_bytes(tmp.data())
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
@@ -120,24 +137,29 @@ impl CtrlAnimeZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.config.builtin_anims_enabled = enabled;
|
self.0.lock().await.config.builtin_anims_enabled = enabled;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
if enabled {
|
if enabled {
|
||||||
lock.thread_exit.store(true, Ordering::Release);
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.thread_exit
|
||||||
|
.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn builtin_animations(&self) -> Animations {
|
async fn builtin_animations(&self) -> Animations {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.builtin_anims
|
||||||
lock.config.builtin_anims
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set which builtin animation is used for each stage
|
/// Set which builtin animation is used for each stage
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_builtin_animations(&self, settings: Animations) {
|
async fn set_builtin_animations(&self, settings: Animations) {
|
||||||
let mut lock = self.0.lock().await;
|
self.0
|
||||||
lock.node
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_builtin_animations(
|
.write_bytes(&pkt_set_builtin_animations(
|
||||||
settings.boot,
|
settings.boot,
|
||||||
settings.awake,
|
settings.awake,
|
||||||
@@ -148,118 +170,128 @@ impl CtrlAnimeZbus {
|
|||||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.node
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(true))
|
.write_bytes(&pkt_set_enable_powersave_anim(true))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.config.display_enabled = true;
|
self.0.lock().await.config.display_enabled = true;
|
||||||
lock.config.builtin_anims = settings;
|
self.0.lock().await.config.builtin_anims = settings;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn enable_display(&self) -> bool {
|
async fn enable_display(&self) -> bool {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.display_enabled
|
||||||
lock.config.display_enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether the AniMe is enabled at all
|
/// Set whether the AniMe is enabled at all
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_enable_display(&self, enabled: bool) {
|
async fn set_enable_display(&self, enabled: bool) {
|
||||||
let mut lock = self.0.lock().await;
|
self.0
|
||||||
lock.node
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(enabled))
|
.write_bytes(&pkt_set_enable_display(enabled))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.config.display_enabled = enabled;
|
self.0.lock().await.config.display_enabled = enabled;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn off_when_unplugged(&self) -> bool {
|
async fn off_when_unplugged(&self) -> bool {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.off_when_unplugged
|
||||||
lock.config.off_when_unplugged
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set if to turn the AniMe Matrix off when external power is unplugged
|
/// Set if to turn the AniMe Matrix off when external power is unplugged
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_off_when_unplugged(&self, enabled: bool) {
|
async fn set_off_when_unplugged(&self, enabled: bool) {
|
||||||
let mut lock = self.0.lock().await;
|
|
||||||
let manager = get_logind_manager().await;
|
let manager = get_logind_manager().await;
|
||||||
let pow = manager.on_external_power().await.unwrap_or_default();
|
let pow = manager.on_external_power().await.unwrap_or_default();
|
||||||
|
|
||||||
lock.node
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(!pow && !enabled))
|
.write_bytes(&pkt_set_enable_display(!pow && !enabled))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
lock.config.off_when_unplugged = enabled;
|
self.0.lock().await.config.off_when_unplugged = enabled;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn off_when_suspended(&self) -> bool {
|
async fn off_when_suspended(&self) -> bool {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.off_when_suspended
|
||||||
lock.config.off_when_suspended
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set if to turn the AniMe Matrix off when the laptop is suspended
|
/// Set if to turn the AniMe Matrix off when the laptop is suspended
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_off_when_suspended(&self, enabled: bool) {
|
async fn set_off_when_suspended(&self, enabled: bool) {
|
||||||
let mut lock = self.0.lock().await;
|
self.0.lock().await.config.off_when_suspended = enabled;
|
||||||
lock.config.off_when_suspended = enabled;
|
self.0.lock().await.config.write();
|
||||||
lock.config.write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn off_when_lid_closed(&self) -> bool {
|
async fn off_when_lid_closed(&self) -> bool {
|
||||||
let lock = self.0.lock().await;
|
self.0.lock().await.config.off_when_lid_closed
|
||||||
lock.config.off_when_lid_closed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set if to turn the AniMe Matrix off when the lid is closed
|
/// Set if to turn the AniMe Matrix off when the lid is closed
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_off_when_lid_closed(&self, enabled: bool) {
|
async fn set_off_when_lid_closed(&self, enabled: bool) {
|
||||||
let mut lock = self.0.lock().await;
|
|
||||||
let manager = get_logind_manager().await;
|
let manager = get_logind_manager().await;
|
||||||
let lid = manager.lid_closed().await.unwrap_or_default();
|
let lid = manager.lid_closed().await.unwrap_or_default();
|
||||||
|
|
||||||
lock.node
|
self.0
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(lid && !enabled))
|
.write_bytes(&pkt_set_enable_display(lid && !enabled))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
lock.config.off_when_lid_closed = enabled;
|
self.0.lock().await.config.off_when_lid_closed = enabled;
|
||||||
lock.config.write();
|
self.0.lock().await.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The main loop is the base system set action if the user isn't running
|
/// The main loop is the base system set action if the user isn't running
|
||||||
/// the user daemon
|
/// the user daemon
|
||||||
async fn run_main_loop(&self, start: bool) {
|
async fn run_main_loop(&self, start: bool) {
|
||||||
if start {
|
if start {
|
||||||
let lock = self.0.lock().await;
|
self.0
|
||||||
lock.thread_exit.store(true, Ordering::SeqCst);
|
.lock()
|
||||||
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false).await;
|
.await
|
||||||
|
.thread_exit
|
||||||
|
.store(true, Ordering::SeqCst);
|
||||||
|
CtrlAnime::run_thread(
|
||||||
|
self.0.clone(),
|
||||||
|
self.0.lock().await.cache.system.clone(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the device state as stored by asusd
|
/// Get the device state as stored by asusd
|
||||||
// #[dbus_interface(property)]
|
// #[zbus(property)]
|
||||||
async fn device_state(&self) -> DeviceState {
|
async fn device_state(&self) -> DeviceState {
|
||||||
let lock = self.0.lock().await;
|
DeviceState::from(&self.0.lock().await.config)
|
||||||
DeviceState::from(&lock.config)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::CtrlTask for CtrlAnimeZbus {
|
impl crate::CtrlTask for CtrlAnimeZbus {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
ANIME_ZBUS_PATH
|
ANIME_ZBUS_PATH
|
||||||
@@ -275,30 +307,53 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
// on_sleep
|
// on_sleep
|
||||||
let inner = inner1.clone();
|
let inner = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner.lock().await;
|
let config = inner.lock().await.config.clone();
|
||||||
if lock.config.display_enabled {
|
if config.display_enabled {
|
||||||
lock.node
|
inner
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(
|
.lock()
|
||||||
!(sleeping && lock.config.off_when_suspended),
|
.await
|
||||||
))
|
.thread_exit
|
||||||
.map_err(|err| {
|
.store(true, Ordering::Release); // ensure clean slate
|
||||||
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
lock.thread_exit.store(true, Ordering::Release); // ensure clean slate
|
inner
|
||||||
lock.node
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(
|
.write_bytes(&pkt_set_enable_display(
|
||||||
!(sleeping && lock.config.off_when_suspended),
|
!(sleeping && config.off_when_suspended),
|
||||||
))
|
))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
if !sleeping && !lock.config.builtin_anims_enabled {
|
if config.builtin_anims_enabled {
|
||||||
CtrlAnime::run_thread(inner.clone(), lock.cache.wake.clone(), true)
|
inner
|
||||||
.await;
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
|
.write_bytes(&pkt_set_enable_powersave_anim(
|
||||||
|
!(sleeping && config.off_when_suspended),
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
} else if !sleeping && !config.builtin_anims_enabled {
|
||||||
|
// Run custom wake animation
|
||||||
|
inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
|
.write_bytes(&pkt_set_enable_powersave_anim(false))
|
||||||
|
.ok(); // ensure builtins are disabled
|
||||||
|
|
||||||
|
CtrlAnime::run_thread(
|
||||||
|
inner.clone(),
|
||||||
|
inner.lock().await.cache.wake.clone(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,14 +362,26 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
// on_shutdown
|
// on_shutdown
|
||||||
let inner = inner2.clone();
|
let inner = inner2.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner.lock().await;
|
let AnimeConfig {
|
||||||
if lock.config.display_enabled && !lock.config.builtin_anims_enabled {
|
display_enabled,
|
||||||
|
builtin_anims_enabled,
|
||||||
|
..
|
||||||
|
} = inner.lock().await.config;
|
||||||
|
if display_enabled && !builtin_anims_enabled {
|
||||||
if shutting_down {
|
if shutting_down {
|
||||||
CtrlAnime::run_thread(inner.clone(), lock.cache.shutdown.clone(), true)
|
CtrlAnime::run_thread(
|
||||||
.await;
|
inner.clone(),
|
||||||
|
inner.lock().await.cache.shutdown.clone(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
} else {
|
} else {
|
||||||
CtrlAnime::run_thread(inner.clone(), lock.cache.boot.clone(), true)
|
CtrlAnime::run_thread(
|
||||||
.await;
|
inner.clone(),
|
||||||
|
inner.lock().await.cache.boot.clone(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,17 +390,27 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
let inner = inner3.clone();
|
let inner = inner3.clone();
|
||||||
// on lid change
|
// on lid change
|
||||||
async move {
|
async move {
|
||||||
let lock = inner.lock().await;
|
let AnimeConfig {
|
||||||
if lock.config.off_when_lid_closed {
|
off_when_lid_closed,
|
||||||
if lock.config.builtin_anims_enabled {
|
builtin_anims_enabled,
|
||||||
lock.node
|
..
|
||||||
|
} = inner.lock().await.config;
|
||||||
|
if off_when_lid_closed {
|
||||||
|
if builtin_anims_enabled {
|
||||||
|
inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(!lid_closed))
|
.write_bytes(&pkt_set_enable_powersave_anim(!lid_closed))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
lock.node
|
inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(!lid_closed))
|
.write_bytes(&pkt_set_enable_display(!lid_closed))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
@@ -346,25 +423,39 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
let inner = inner4.clone();
|
let inner = inner4.clone();
|
||||||
// on power change
|
// on power change
|
||||||
async move {
|
async move {
|
||||||
let lock = inner.lock().await;
|
let AnimeConfig {
|
||||||
if lock.config.off_when_unplugged {
|
off_when_unplugged,
|
||||||
if lock.config.builtin_anims_enabled {
|
builtin_anims_enabled,
|
||||||
lock.node
|
brightness_on_battery,
|
||||||
|
..
|
||||||
|
} = inner.lock().await.config;
|
||||||
|
if off_when_unplugged {
|
||||||
|
if builtin_anims_enabled {
|
||||||
|
inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(power_plugged))
|
.write_bytes(&pkt_set_enable_powersave_anim(power_plugged))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
lock.node
|
inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
.write_bytes(&pkt_set_enable_display(power_plugged))
|
.write_bytes(&pkt_set_enable_display(power_plugged))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
} else {
|
} else {
|
||||||
lock.node
|
inner
|
||||||
.write_bytes(&pkt_set_brightness(lock.config.brightness_on_battery))
|
.lock()
|
||||||
|
.await
|
||||||
|
.node
|
||||||
|
.write_bytes(&pkt_set_brightness(brightness_on_battery))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
||||||
})
|
})
|
||||||
@@ -379,7 +470,6 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::Reloadable for CtrlAnimeZbus {
|
impl crate::Reloadable for CtrlAnimeZbus {
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Some(lock) = self.0.try_lock() {
|
if let Some(lock) = self.0.try_lock() {
|
||||||
|
|||||||
+30
-142
@@ -1,167 +1,59 @@
|
|||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use log::{debug, warn};
|
use log::{debug, info, warn};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::power::AuraPower;
|
use rog_aura::keyboard::LaptopAuraPower;
|
||||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::{
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT,
|
||||||
use rog_platform::hid_raw::HidRaw;
|
};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "aura.ron";
|
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
|
||||||
|
|
||||||
/// Enable/disable LED control in various states such as
|
|
||||||
/// when the device is awake, suspended, shutting down or
|
|
||||||
/// booting.
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum AuraPowerConfig {
|
|
||||||
AuraDevTuf(HashSet<AuraDevTuf>),
|
|
||||||
AuraDevRog1(HashSet<AuraDevRog1>),
|
|
||||||
AuraDevRog2(AuraPower),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuraPowerConfig {
|
|
||||||
/// Invalid for TUF laptops
|
|
||||||
pub fn to_bytes(control: &Self) -> [u8; 4] {
|
|
||||||
match control {
|
|
||||||
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0, 0],
|
|
||||||
AuraPowerConfig::AuraDevRog1(c) => {
|
|
||||||
let c: Vec<AuraDevRog1> = c.iter().copied().collect();
|
|
||||||
AuraDevRog1::to_bytes(&c)
|
|
||||||
}
|
|
||||||
AuraPowerConfig::AuraDevRog2(c) => c.to_bytes(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_tuf_bool_array(control: &Self) -> Option<[bool; 5]> {
|
|
||||||
if let Self::AuraDevTuf(c) = control {
|
|
||||||
return Some([
|
|
||||||
true,
|
|
||||||
c.contains(&AuraDevTuf::Boot),
|
|
||||||
c.contains(&AuraDevTuf::Awake),
|
|
||||||
c.contains(&AuraDevTuf::Sleep),
|
|
||||||
c.contains(&AuraDevTuf::Keyboard),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Self::AuraDevRog1(c) = control {
|
|
||||||
return Some([
|
|
||||||
true,
|
|
||||||
c.contains(&AuraDevRog1::Boot),
|
|
||||||
c.contains(&AuraDevRog1::Awake),
|
|
||||||
c.contains(&AuraDevRog1::Sleep),
|
|
||||||
c.contains(&AuraDevRog1::Keyboard),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_tuf(&mut self, power: AuraDevTuf, on: bool) {
|
|
||||||
if let Self::AuraDevTuf(p) = self {
|
|
||||||
if on {
|
|
||||||
p.insert(power);
|
|
||||||
} else {
|
|
||||||
p.remove(&power);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_0x1866(&mut self, power: AuraDevRog1, on: bool) {
|
|
||||||
if let Self::AuraDevRog1(p) = self {
|
|
||||||
if on {
|
|
||||||
p.insert(power);
|
|
||||||
} else {
|
|
||||||
p.remove(&power);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_0x19b6(&mut self, power: AuraPower) {
|
|
||||||
if let Self::AuraDevRog2(p) = self {
|
|
||||||
*p = power;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&AuraPowerConfig> for AuraPowerDev {
|
|
||||||
fn from(config: &AuraPowerConfig) -> Self {
|
|
||||||
match config {
|
|
||||||
AuraPowerConfig::AuraDevTuf(d) => AuraPowerDev {
|
|
||||||
tuf: d.iter().copied().collect(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
AuraPowerConfig::AuraDevRog1(d) => AuraPowerDev {
|
|
||||||
old_rog: d.iter().copied().collect(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
AuraPowerConfig::AuraDevRog2(d) => AuraPowerDev {
|
|
||||||
rog: d.clone(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
|
||||||
// #[serde(default)]
|
// #[serde(default)]
|
||||||
pub struct AuraConfig {
|
pub struct AuraConfig {
|
||||||
|
pub config_name: String,
|
||||||
pub brightness: LedBrightness,
|
pub brightness: LedBrightness,
|
||||||
pub current_mode: AuraModeNum,
|
pub current_mode: AuraModeNum,
|
||||||
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
|
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
|
||||||
pub multizone: Option<BTreeMap<AuraModeNum, Vec<AuraEffect>>>,
|
pub multizone: Option<BTreeMap<AuraModeNum, Vec<AuraEffect>>>,
|
||||||
pub multizone_on: bool,
|
pub multizone_on: bool,
|
||||||
pub enabled: AuraPowerConfig,
|
pub enabled: LaptopAuraPower,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for AuraConfig {
|
impl StdConfig for AuraConfig {
|
||||||
/// Detect the keyboard type and load from default DB if data available
|
/// Detect the keyboard type and load from default DB if data available
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
warn!("AuraConfig: creating new config");
|
panic!("This should not be used");
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
}
|
||||||
for prod in ASUS_KEYBOARD_DEVICES {
|
|
||||||
if HidRaw::new(prod.into()).is_ok() {
|
fn file_name(&self) -> String {
|
||||||
prod_id = prod;
|
if self.config_name.is_empty() {
|
||||||
break;
|
panic!("Config file name should not be empty");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::from_default_support(prod_id, &LaptopLedData::get_data())
|
self.config_name.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
fn config_dir() -> std::path::PathBuf {
|
||||||
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
|
||||||
CONFIG_FILE.to_owned()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad for AuraConfig {}
|
impl StdConfigLoad for AuraConfig {}
|
||||||
|
|
||||||
impl AuraConfig {
|
impl AuraConfig {
|
||||||
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
/// Detect the keyboard type and load from default DB if data available
|
||||||
|
pub fn new(prod_id: &str) -> Self {
|
||||||
|
info!("Setting up AuraConfig for {prod_id:?}");
|
||||||
// create a default config here
|
// create a default config here
|
||||||
let enabled = if prod_id.is_new_style() {
|
let device_type = AuraDeviceType::from(prod_id);
|
||||||
AuraPowerConfig::AuraDevRog2(AuraPower::new_all_on())
|
if device_type == AuraDeviceType::Unknown {
|
||||||
} else if prod_id.is_tuf_style() {
|
warn!("idProduct:{prod_id:?} is unknown");
|
||||||
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
}
|
||||||
AuraDevTuf::Awake,
|
let support_data = LedSupportData::get_data(prod_id);
|
||||||
AuraDevTuf::Boot,
|
let enabled = LaptopAuraPower::new(device_type, &support_data);
|
||||||
AuraDevTuf::Sleep,
|
|
||||||
AuraDevTuf::Keyboard,
|
|
||||||
]))
|
|
||||||
} else {
|
|
||||||
AuraPowerConfig::AuraDevRog1(HashSet::from([
|
|
||||||
AuraDevRog1::Awake,
|
|
||||||
AuraDevRog1::Boot,
|
|
||||||
AuraDevRog1::Sleep,
|
|
||||||
AuraDevRog1::Keyboard,
|
|
||||||
AuraDevRog1::Lightbar,
|
|
||||||
]))
|
|
||||||
};
|
|
||||||
let mut config = AuraConfig {
|
let mut config = AuraConfig {
|
||||||
|
config_name: format!("aura_{prod_id}.ron"),
|
||||||
brightness: LedBrightness::Med,
|
brightness: LedBrightness::Med,
|
||||||
current_mode: AuraModeNum::Static,
|
current_mode: AuraModeNum::Static,
|
||||||
builtins: BTreeMap::new(),
|
builtins: BTreeMap::new(),
|
||||||
@@ -171,7 +63,7 @@ impl AuraConfig {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for n in &support_data.basic_modes {
|
for n in &support_data.basic_modes {
|
||||||
debug!("AuraConfig: creating default for {n}");
|
debug!("creating default for {n}");
|
||||||
config
|
config
|
||||||
.builtins
|
.builtins
|
||||||
.insert(*n, AuraEffect::default_with_mode(*n));
|
.insert(*n, AuraEffect::default_with_mode(*n));
|
||||||
@@ -241,16 +133,13 @@ impl AuraConfig {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
|
||||||
use rog_aura::usb::AuraDevice;
|
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||||
|
|
||||||
use super::AuraConfig;
|
use super::AuraConfig;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_4key_config() {
|
fn set_multizone_4key_config() {
|
||||||
let mut config =
|
let mut config = AuraConfig::new("19b6");
|
||||||
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
@@ -340,8 +229,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_multimode_config() {
|
fn set_multizone_multimode_config() {
|
||||||
let mut config =
|
let mut config = AuraConfig::new("19b6");
|
||||||
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
zone: AuraZone::Key1,
|
zone: AuraZone::Key1,
|
||||||
|
|||||||
@@ -1,82 +1,176 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashSet};
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use dmi_id::DMIID;
|
use inotify::Inotify;
|
||||||
use log::{info, warn};
|
use log::{debug, info, warn};
|
||||||
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::keyboard::{LedUsbPackets, UsbPackets};
|
||||||
use rog_aura::usb::{AuraDevice, LED_APPLY, LED_SET};
|
use rog_aura::usb::{LED_APPLY, LED_SET};
|
||||||
use rog_aura::{AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN};
|
use rog_aura::{
|
||||||
|
AuraDeviceType, AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN,
|
||||||
|
};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
|
||||||
use super::config::{AuraConfig, AuraPowerConfig};
|
use super::config::AuraConfig;
|
||||||
|
use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf};
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LEDNode {
|
pub enum LEDNode {
|
||||||
|
/// Brightness and/or TUF RGB controls
|
||||||
KbdLed(KeyboardLed),
|
KbdLed(KeyboardLed),
|
||||||
Rog(HidRaw),
|
/// Raw HID handle
|
||||||
None,
|
Rog(KeyboardLed, HidRaw),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LEDNode {
|
||||||
|
// TODO: move various methods upwards to this
|
||||||
|
pub fn set_brightness(&self, value: u8) -> Result<(), RogError> {
|
||||||
|
match self {
|
||||||
|
LEDNode::KbdLed(k) => k.set_brightness(value)?,
|
||||||
|
LEDNode::Rog(k, _) => k.set_brightness(value)?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_brightness(&self) -> Result<u8, RogError> {
|
||||||
|
Ok(match self {
|
||||||
|
LEDNode::KbdLed(k) => k.get_brightness()?,
|
||||||
|
LEDNode::Rog(k, _) => k.get_brightness()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn monitor_brightness(&self) -> Result<Inotify, RogError> {
|
||||||
|
Ok(match self {
|
||||||
|
LEDNode::KbdLed(k) => k.monitor_brightness()?,
|
||||||
|
LEDNode::Rog(k, _) => k.monitor_brightness()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Individual controller for one Aura device
|
||||||
pub struct CtrlKbdLed {
|
pub struct CtrlKbdLed {
|
||||||
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
pub led_type: AuraDeviceType,
|
||||||
pub led_prod: AuraDevice,
|
|
||||||
pub led_node: LEDNode,
|
pub led_node: LEDNode,
|
||||||
pub sysfs_node: KeyboardLed,
|
pub supported_data: LedSupportData, // TODO: is storing this really required?
|
||||||
pub supported_modes: LaptopLedData,
|
|
||||||
pub per_key_mode_active: bool,
|
pub per_key_mode_active: bool,
|
||||||
pub config: AuraConfig,
|
pub config: AuraConfig,
|
||||||
|
pub dbus_path: OwnedObjectPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlKbdLed {
|
impl CtrlKbdLed {
|
||||||
pub fn new(supported_modes: LaptopLedData) -> Result<Self, RogError> {
|
pub fn find_all() -> Result<Vec<Self>, RogError> {
|
||||||
let mut led_prod = AuraDevice::Unknown;
|
info!("Searching for all Aura devices");
|
||||||
let mut usb_node = None;
|
let mut devices = Vec::new();
|
||||||
for prod in ASUS_KEYBOARD_DEVICES {
|
let mut found = HashSet::new(); // track and ensure we use only one hidraw per prod_id
|
||||||
match HidRaw::new(prod.into()) {
|
|
||||||
Ok(node) => {
|
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||||
led_prod = prod;
|
warn!("{}", err);
|
||||||
usb_node = Some(node);
|
err
|
||||||
info!(
|
})?;
|
||||||
"Looked for keyboard controller 0x{}: Found",
|
|
||||||
<&str>::from(prod)
|
enumerator.match_subsystem("hidraw").map_err(|err| {
|
||||||
);
|
warn!("{}", err);
|
||||||
break;
|
err
|
||||||
|
})?;
|
||||||
|
|
||||||
|
for end_point in enumerator.scan_devices()? {
|
||||||
|
// usb_device gives us a product and vendor ID
|
||||||
|
if let Some(usb_device) =
|
||||||
|
end_point.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||||
|
{
|
||||||
|
// The asus_wmi driver latches MCU that controls the USB endpoints
|
||||||
|
if let Some(parent) = end_point.parent() {
|
||||||
|
if let Some(driver) = parent.driver() {
|
||||||
|
// There is a tree of devices added so filter by driver
|
||||||
|
if driver != "asus" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => info!(
|
// Device is something like 002, while its parent is the MCU
|
||||||
"Looked for keyboard controller 0x{}: {err}",
|
// Think of it like the device is an endpoint of the USB device attached
|
||||||
<&str>::from(prod)
|
let mut prod_id = String::new();
|
||||||
),
|
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||||
|
prod_id = usb_id.to_string_lossy().to_string();
|
||||||
|
let aura_dev = AuraDeviceType::from(prod_id.as_str());
|
||||||
|
if aura_dev == AuraDeviceType::Unknown || found.contains(&aura_dev) {
|
||||||
|
log::debug!("Unknown or invalid device: {usb_id:?}, skipping");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found.insert(aura_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
let dev_node = if let Some(dev_node) = usb_device.devnode() {
|
||||||
|
dev_node
|
||||||
|
} else {
|
||||||
|
debug!("Device has no devnode, skipping");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
info!("AuraControl found device at: {:?}", dev_node);
|
||||||
|
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
|
||||||
|
let dev = HidRaw::from_device(end_point)?;
|
||||||
|
let mut dev = Self::from_hidraw(dev, dbus_path)?;
|
||||||
|
dev.config = Self::init_config(&prod_id);
|
||||||
|
devices.push(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a TUF laptop LED. Assume there is only ever one.
|
||||||
|
if let Ok(tuf_kbd) = KeyboardLed::new() {
|
||||||
|
if tuf_kbd.has_kbd_rgb_mode() {
|
||||||
|
info!("AuraControl found a TUF laptop keyboard");
|
||||||
|
let ctrl = CtrlKbdLed {
|
||||||
|
led_type: AuraDeviceType::LaptopTuf,
|
||||||
|
led_node: LEDNode::KbdLed(tuf_kbd),
|
||||||
|
supported_data: LedSupportData::get_data("tuf"),
|
||||||
|
per_key_mode_active: false,
|
||||||
|
config: Self::init_config("tuf"),
|
||||||
|
dbus_path: dbus_path_for_tuf(),
|
||||||
|
};
|
||||||
|
devices.push(ctrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Found {} Aura devices", devices.len());
|
||||||
|
|
||||||
|
Ok(devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The generated data from this function has a default config. This config
|
||||||
|
/// should be overwritten. The reason for the default config is because
|
||||||
|
/// of async issues between this and udev/hidraw
|
||||||
|
pub fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result<Self, RogError> {
|
||||||
let rgb_led = KeyboardLed::new()?;
|
let rgb_led = KeyboardLed::new()?;
|
||||||
|
let prod_id = AuraDeviceType::from(device.prod_id());
|
||||||
if usb_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
if prod_id == AuraDeviceType::Unknown {
|
||||||
let dmi = DMIID::new().unwrap_or_default();
|
log::error!("{} is AuraDevice::Unknown", device.prod_id());
|
||||||
if dmi.dmi_family.contains("TUF") {
|
return Err(RogError::NoAuraNode);
|
||||||
warn!(
|
|
||||||
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 kernel \
|
|
||||||
and a supported TUF laptop"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Err(RogError::NoAuraKeyboard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let led_node = if let Some(rog) = usb_node {
|
// New loads data from the DB also
|
||||||
info!("Found ROG USB keyboard");
|
// let config = Self::init_config(prod_id, data);
|
||||||
LEDNode::Rog(rog)
|
|
||||||
} else if rgb_led.has_kbd_rgb_mode() {
|
|
||||||
info!("Found TUF keyboard");
|
|
||||||
LEDNode::KbdLed(rgb_led.clone())
|
|
||||||
} else {
|
|
||||||
LEDNode::None
|
|
||||||
};
|
|
||||||
|
|
||||||
// New loads data fromt he DB also
|
let data = LedSupportData::get_data(device.prod_id());
|
||||||
let mut config_init = AuraConfig::new();
|
let ctrl = CtrlKbdLed {
|
||||||
|
led_type: prod_id,
|
||||||
|
led_node: LEDNode::Rog(rgb_led, device),
|
||||||
|
supported_data: data.clone(),
|
||||||
|
per_key_mode_active: false,
|
||||||
|
config: AuraConfig::default(),
|
||||||
|
dbus_path,
|
||||||
|
};
|
||||||
|
Ok(ctrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_config(prod_id: &str) -> AuraConfig {
|
||||||
|
// New loads data from the DB also
|
||||||
|
let mut config_init = AuraConfig::new(prod_id);
|
||||||
|
// config_init.set_filename(prod_id);
|
||||||
let mut config_loaded = config_init.clone().load();
|
let mut config_loaded = config_init.clone().load();
|
||||||
// update the initialised data with what we loaded from disk
|
// update the initialised data with what we loaded from disk
|
||||||
for mode in &mut config_init.builtins {
|
for mode in &mut config_init.builtins {
|
||||||
@@ -95,9 +189,10 @@ impl CtrlKbdLed {
|
|||||||
// update init values from loaded values if they exist
|
// update init values from loaded values if they exist
|
||||||
if let Some(loaded) = multizone_loaded.get(mode.0) {
|
if let Some(loaded) = multizone_loaded.get(mode.0) {
|
||||||
let mut new_set = Vec::new();
|
let mut new_set = Vec::new();
|
||||||
|
let data = LedSupportData::get_data(prod_id);
|
||||||
// only reuse a zone mode if the mode is supported
|
// only reuse a zone mode if the mode is supported
|
||||||
for mode in loaded {
|
for mode in loaded {
|
||||||
if supported_modes.basic_modes.contains(&mode.mode) {
|
if data.basic_modes.contains(&mode.mode) {
|
||||||
new_set.push(mode.clone());
|
new_set.push(mode.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,27 +202,21 @@ impl CtrlKbdLed {
|
|||||||
*multizone_loaded = multizone_init;
|
*multizone_loaded = multizone_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctrl = CtrlKbdLed {
|
config_loaded
|
||||||
led_prod,
|
|
||||||
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
|
||||||
sysfs_node: rgb_led, // If was none then we already returned above
|
|
||||||
supported_modes,
|
|
||||||
per_key_mode_active: false,
|
|
||||||
config: config_loaded,
|
|
||||||
};
|
|
||||||
Ok(ctrl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set combination state for boot animation/sleep animation/all leds/keys
|
/// Set combination state for boot animation/sleep animation/all leds/keys
|
||||||
/// leds/side leds LED active
|
/// leds/side leds LED active
|
||||||
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
||||||
if let LEDNode::KbdLed(platform) = &mut self.led_node {
|
if let LEDNode::KbdLed(_platform) = &mut self.led_node {
|
||||||
if let Some(pwr) = AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
|
// TODO: tuf bool array
|
||||||
let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, pwr[4] as u8];
|
// if let Some(pwr) =
|
||||||
platform.set_kbd_rgb_state(&buf)?;
|
// AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
|
||||||
}
|
// let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8,
|
||||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
// pwr[4] as u8]; platform.set_kbd_rgb_state(&buf)?;
|
||||||
let bytes = AuraPowerConfig::to_bytes(&self.config.enabled);
|
// }
|
||||||
|
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
|
let bytes = self.config.enabled.to_bytes(self.led_type);
|
||||||
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
||||||
|
|
||||||
hid_raw.write_bytes(&message)?;
|
hid_raw.write_bytes(&message)?;
|
||||||
@@ -152,20 +241,20 @@ impl CtrlKbdLed {
|
|||||||
|
|
||||||
if pkt_type != PER_KEY_TYPE {
|
if pkt_type != PER_KEY_TYPE {
|
||||||
self.per_key_mode_active = false;
|
self.per_key_mode_active = false;
|
||||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
hid_raw.write_bytes(&effect[0])?;
|
hid_raw.write_bytes(&effect[0])?;
|
||||||
hid_raw.write_bytes(&LED_SET)?;
|
hid_raw.write_bytes(&LED_SET)?;
|
||||||
// hid_raw.write_bytes(&LED_APPLY)?;
|
// hid_raw.write_bytes(&LED_APPLY)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !self.per_key_mode_active {
|
if !self.per_key_mode_active {
|
||||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
let init = LedUsbPackets::get_init_msg();
|
let init = LedUsbPackets::get_init_msg();
|
||||||
hid_raw.write_bytes(&init)?;
|
hid_raw.write_bytes(&init)?;
|
||||||
}
|
}
|
||||||
self.per_key_mode_active = true;
|
self.per_key_mode_active = true;
|
||||||
}
|
}
|
||||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
for row in effect.iter() {
|
for row in effect.iter() {
|
||||||
hid_raw.write_bytes(row)?;
|
hid_raw.write_bytes(row)?;
|
||||||
}
|
}
|
||||||
@@ -192,7 +281,7 @@ impl CtrlKbdLed {
|
|||||||
mode.speed as u8,
|
mode.speed as u8,
|
||||||
];
|
];
|
||||||
platform.set_kbd_rgb_mode(&buf)?;
|
platform.set_kbd_rgb_mode(&buf)?;
|
||||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||||
hid_raw.write_bytes(&bytes)?;
|
hid_raw.write_bytes(&bytes)?;
|
||||||
hid_raw.write_bytes(&LED_SET)?;
|
hid_raw.write_bytes(&LED_SET)?;
|
||||||
@@ -245,7 +334,7 @@ impl CtrlKbdLed {
|
|||||||
/// exists.
|
/// exists.
|
||||||
fn create_multizone_default(&mut self) -> Result<(), RogError> {
|
fn create_multizone_default(&mut self) -> Result<(), RogError> {
|
||||||
let mut default = vec![];
|
let mut default = vec![];
|
||||||
for (i, tmp) in self.supported_modes.basic_zones.iter().enumerate() {
|
for (i, tmp) in self.supported_data.basic_zones.iter().enumerate() {
|
||||||
default.push(AuraEffect {
|
default.push(AuraEffect {
|
||||||
mode: self.config.current_mode,
|
mode: self.config.current_mode,
|
||||||
zone: *tmp,
|
zone: *tmp,
|
||||||
@@ -272,42 +361,45 @@ impl CtrlKbdLed {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rog_aura::aura_detection::{LaptopLedData, PowerZones};
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::usb::AuraDevice;
|
use rog_aura::{AuraDeviceType, AuraModeNum, AuraZone, PowerZones};
|
||||||
use rog_aura::{AuraModeNum, AuraZone};
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
|
||||||
use super::CtrlKbdLed;
|
use super::CtrlKbdLed;
|
||||||
use crate::ctrl_aura::config::AuraConfig;
|
use crate::ctrl_aura::config::AuraConfig;
|
||||||
use crate::ctrl_aura::controller::LEDNode;
|
use crate::ctrl_aura::controller::LEDNode;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "Unable to run in CI as the HIDRAW device is required"]
|
||||||
fn create_multizone_if_no_config() {
|
fn create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
let config = AuraConfig::new("19b6");
|
||||||
let supported_modes = LaptopLedData {
|
let supported_basic_modes = LedSupportData {
|
||||||
board_name: String::new(),
|
device_name: String::new(),
|
||||||
|
product_id: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
basic_modes: vec![AuraModeNum::Static],
|
basic_modes: vec![AuraModeNum::Static],
|
||||||
basic_zones: vec![],
|
basic_zones: vec![],
|
||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::keyboard::AdvancedAuraType::None,
|
||||||
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
|
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: AuraDevice::X19b6,
|
led_type: AuraDeviceType::LaptopPost2021,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("19b6").unwrap()),
|
||||||
sysfs_node: KeyboardLed::default(),
|
supported_data: supported_basic_modes,
|
||||||
supported_modes,
|
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
|
dbus_path: OwnedObjectPath::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(controller.config.multizone.is_none());
|
assert!(controller.config.multizone.is_none());
|
||||||
assert!(controller.create_multizone_default().is_err());
|
assert!(controller.create_multizone_default().is_err());
|
||||||
assert!(controller.config.multizone.is_none());
|
assert!(controller.config.multizone.is_none());
|
||||||
|
|
||||||
controller.supported_modes.basic_zones.push(AuraZone::Key1);
|
controller.supported_data.basic_zones.push(AuraZone::Key1);
|
||||||
controller.supported_modes.basic_zones.push(AuraZone::Key2);
|
controller.supported_data.basic_zones.push(AuraZone::Key2);
|
||||||
assert!(controller.create_multizone_default().is_ok());
|
assert!(controller.create_multizone_default().is_ok());
|
||||||
assert!(controller.config.multizone.is_some());
|
assert!(controller.config.multizone.is_some());
|
||||||
|
|
||||||
@@ -320,24 +412,27 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "Unable to run in CI as the HIDRAW device is required"]
|
||||||
|
// TODO: use sim device
|
||||||
fn next_mode_create_multizone_if_no_config() {
|
fn next_mode_create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
let config = AuraConfig::new("19b6");
|
||||||
let supported_modes = LaptopLedData {
|
let supported_basic_modes = LedSupportData {
|
||||||
board_name: String::new(),
|
device_name: String::new(),
|
||||||
|
product_id: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
basic_modes: vec![AuraModeNum::Static],
|
basic_modes: vec![AuraModeNum::Static],
|
||||||
basic_zones: vec![AuraZone::Key1, AuraZone::Key2],
|
basic_zones: vec![AuraZone::Key1, AuraZone::Key2],
|
||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::keyboard::AdvancedAuraType::None,
|
||||||
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
|
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: AuraDevice::X19b6,
|
led_type: AuraDeviceType::LaptopPost2021,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("19b6").unwrap()),
|
||||||
sysfs_node: KeyboardLed::default(),
|
supported_data: supported_basic_modes,
|
||||||
supported_modes,
|
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
|
dbus_path: OwnedObjectPath::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(controller.config.multizone.is_none());
|
assert!(controller.config.multizone.is_none());
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
// Plan:
|
||||||
|
// - Manager has udev monitor on USB looking for ROG devices
|
||||||
|
// - If a device is found, add it to watch
|
||||||
|
// - Add it to Zbus server
|
||||||
|
// - If udev sees device removed then remove the zbus path
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use log::{debug, error, info, warn};
|
||||||
|
use mio::{Events, Interest, Poll, Token};
|
||||||
|
use rog_aura::AuraDeviceType;
|
||||||
|
use rog_platform::hid_raw::HidRaw;
|
||||||
|
use tokio::task::spawn_blocking;
|
||||||
|
use udev::{Device, MonitorBuilder};
|
||||||
|
use zbus::object_server::SignalContext;
|
||||||
|
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
|
||||||
|
use zbus::Connection;
|
||||||
|
|
||||||
|
use crate::ctrl_aura::controller::CtrlKbdLed;
|
||||||
|
use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_PATH};
|
||||||
|
use crate::error::RogError;
|
||||||
|
use crate::{CtrlTask, Reloadable};
|
||||||
|
|
||||||
|
pub struct AuraManager {
|
||||||
|
_connection: Connection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuraManager {
|
||||||
|
pub async fn new(connection: Connection) -> Result<Self, RogError> {
|
||||||
|
let conn_copy = connection.clone();
|
||||||
|
let mut interfaces = HashSet::new();
|
||||||
|
|
||||||
|
// Do the initial keyboard detection:
|
||||||
|
let all = CtrlKbdLed::find_all()?;
|
||||||
|
for ctrl in all {
|
||||||
|
let path = ctrl.dbus_path.clone();
|
||||||
|
interfaces.insert(path.clone()); // ensure we record the initial stuff
|
||||||
|
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
|
||||||
|
let sig_ctx2 = sig_ctx.clone();
|
||||||
|
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||||
|
start_tasks(zbus, connection.clone(), sig_ctx2, path).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let manager = Self {
|
||||||
|
_connection: connection,
|
||||||
|
};
|
||||||
|
|
||||||
|
// detect all plugged in aura devices (eventually)
|
||||||
|
// only USB devices are detected for here
|
||||||
|
spawn_blocking(move || {
|
||||||
|
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
|
||||||
|
let mut poll = Poll::new()?;
|
||||||
|
let mut events = Events::with_capacity(1024);
|
||||||
|
poll.registry()
|
||||||
|
.register(&mut monitor, Token(0), Interest::READABLE)?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if poll.poll(&mut events, None).is_err() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for event in monitor.iter() {
|
||||||
|
let parent = if let Some(parent) =
|
||||||
|
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||||
|
{
|
||||||
|
parent
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let action = if let Some(action) = event.action() {
|
||||||
|
action
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let id_product = if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||||
|
id_product.to_string_lossy()
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let aura_device = AuraDeviceType::from(&*id_product);
|
||||||
|
if aura_device == AuraDeviceType::Unknown {
|
||||||
|
warn!("idProduct:{id_product:?} is unknown, not using");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "remove" {
|
||||||
|
if interfaces.remove(&path) {
|
||||||
|
info!("AuraManager removing: {path:?}");
|
||||||
|
let conn_copy = conn_copy.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let res = conn_copy
|
||||||
|
.object_server()
|
||||||
|
.remove::<CtrlAuraZbus, _>(&path)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to remove {path:?}, {e:?}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
info!("AuraManager removed: {path:?}, {res}");
|
||||||
|
Ok::<(), RogError>(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if action == "add" {
|
||||||
|
if interfaces.contains(&path) {
|
||||||
|
debug!("Already a ctrl at {path:?}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to check the driver is asus to prevent using hid_generic
|
||||||
|
if let Some(p2) = event.parent() {
|
||||||
|
if let Some(driver) = p2.driver() {
|
||||||
|
// There is a tree of devices added so filter by driver
|
||||||
|
if driver != "asus" {
|
||||||
|
debug!("{id_product:?} driver was not asus, skipping");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(dev_node) = event.devnode() {
|
||||||
|
if let Ok(raw) = HidRaw::from_device(event.device())
|
||||||
|
.map_err(|e| error!("device path error: {e:?}"))
|
||||||
|
{
|
||||||
|
if let Ok(mut ctrl) = CtrlKbdLed::from_hidraw(raw, path.clone()) {
|
||||||
|
ctrl.config = CtrlKbdLed::init_config(&id_product);
|
||||||
|
interfaces.insert(path.clone());
|
||||||
|
info!("AuraManager starting device at: {dev_node:?}, {path:?}");
|
||||||
|
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||||
|
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||||
|
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||||
|
let conn_copy = conn_copy.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
start_tasks(zbus, conn_copy.clone(), sig_ctx, path).await
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Required for return type on spawn
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
Ok::<(), RogError>(())
|
||||||
|
});
|
||||||
|
Ok(manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
|
||||||
|
if let Some(filename) = super::filename_partial(parent) {
|
||||||
|
return Some(
|
||||||
|
ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/{filename}")).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn dbus_path_for_tuf() -> OwnedObjectPath {
|
||||||
|
ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/tuf")).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_tasks(
|
||||||
|
mut zbus: CtrlAuraZbus,
|
||||||
|
connection: Connection,
|
||||||
|
_signal_ctx: SignalContext<'static>,
|
||||||
|
path: OwnedObjectPath,
|
||||||
|
) -> Result<(), RogError> {
|
||||||
|
// let task = zbus.clone();
|
||||||
|
// let signal_ctx = signal_ctx.clone();
|
||||||
|
zbus.reload()
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||||
|
connection.object_server().at(path, zbus).await.unwrap();
|
||||||
|
// TODO: skip this until we keep handles to tasks so they can be killed
|
||||||
|
// task.create_tasks(signal_ctx).await
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,4 +1,29 @@
|
|||||||
|
use udev::Device;
|
||||||
|
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
|
pub mod manager;
|
||||||
/// Implements `CtrlTask`, `Reloadable`, `ZbusRun`
|
/// Implements `CtrlTask`, `Reloadable`, `ZbusRun`
|
||||||
pub mod trait_impls;
|
pub mod trait_impls;
|
||||||
|
|
||||||
|
/// Returns only the Device details concatenated in a form usable for
|
||||||
|
/// adding/appending to a filename
|
||||||
|
pub(super) fn filename_partial(parent: &Device) -> Option<OwnedObjectPath> {
|
||||||
|
if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||||
|
let id_product = id_product.to_string_lossy();
|
||||||
|
let path = if let Some(devnum) = parent.attribute_value("devnum") {
|
||||||
|
let devnum = devnum.to_string_lossy();
|
||||||
|
if let Some(devpath) = parent.attribute_value("devpath") {
|
||||||
|
let devpath = devpath.to_string_lossy();
|
||||||
|
format!("{id_product}_{devnum}_{devpath}")
|
||||||
|
} else {
|
||||||
|
format!("{id_product}_{devnum}")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format!("{id_product}")
|
||||||
|
};
|
||||||
|
return Some(ObjectPath::from_str_unchecked(&path).into());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,30 +1,32 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_aura::advanced::UsbPackets;
|
use rog_aura::keyboard::{LaptopAuraPower, UsbPackets};
|
||||||
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
use rog_aura::{AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, LedBrightness, PowerZones};
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
|
||||||
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
||||||
use zbus::export::futures_util::StreamExt;
|
use zbus::export::futures_util::StreamExt;
|
||||||
use zbus::fdo::Error as ZbErr;
|
use zbus::fdo::Error as ZbErr;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{interface, SignalContext};
|
||||||
|
|
||||||
use super::controller::CtrlKbdLed;
|
use super::controller::CtrlKbdLed;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::CtrlTask;
|
use crate::CtrlTask;
|
||||||
|
|
||||||
pub const AURA_ZBUS_NAME: &str = "Aura";
|
pub const AURA_ZBUS_NAME: &str = "Aura";
|
||||||
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura";
|
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux";
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CtrlAuraZbus(pub Arc<Mutex<CtrlKbdLed>>);
|
pub struct CtrlAuraZbus(Arc<Mutex<CtrlKbdLed>>, SignalContext<'static>);
|
||||||
|
|
||||||
impl CtrlAuraZbus {
|
impl CtrlAuraZbus {
|
||||||
|
pub fn new(controller: CtrlKbdLed, signal: SignalContext<'static>) -> Self {
|
||||||
|
Self(Arc::new(Mutex::new(controller)), signal)
|
||||||
|
}
|
||||||
|
|
||||||
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
||||||
let bright = lock.sysfs_node.get_brightness()?;
|
let bright = lock.led_node.get_brightness()?;
|
||||||
lock.config.read();
|
lock.config.read();
|
||||||
lock.config.brightness = bright.into();
|
lock.config.brightness = bright.into();
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
@@ -32,41 +34,34 @@ impl CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
/// The main interface for changing, reading, or notfying
|
||||||
impl crate::ZbusRun for CtrlAuraZbus {
|
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
|
||||||
Self::add_to_server_helper(self, AURA_ZBUS_PATH, server).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The main interface for changing, reading, or notfying signals
|
|
||||||
///
|
///
|
||||||
/// LED commands are split between Brightness, Modes, Per-Key
|
/// LED commands are split between Brightness, Modes, Per-Key
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[interface(name = "org.asuslinux.Aura")]
|
||||||
impl CtrlAuraZbus {
|
impl CtrlAuraZbus {
|
||||||
/// Return the device type for this Aura keyboard
|
/// Return the device type for this Aura keyboard
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn device_type(&self) -> AuraDevice {
|
async fn device_type(&self) -> AuraDeviceType {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
ctrl.led_prod
|
ctrl.led_type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current LED brightness
|
/// Return the current LED brightness
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
|
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
|
Ok(ctrl.led_node.get_brightness().map(|n| n.into())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the keyboard brightness level (0-3)
|
/// Set the keyboard brightness level (0-3)
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
Ok(ctrl.sysfs_node.set_brightness(brightness.into())?)
|
Ok(ctrl.led_node.set_brightness(brightness.into())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Total levels of brightness available
|
/// Total levels of brightness available
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn supported_brightness(&self) -> Vec<LedBrightness> {
|
async fn supported_brightness(&self) -> Vec<LedBrightness> {
|
||||||
vec![
|
vec![
|
||||||
LedBrightness::Off,
|
LedBrightness::Off,
|
||||||
@@ -77,14 +72,26 @@ impl CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The total available modes
|
/// The total available modes
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn supported_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
|
async fn supported_basic_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
Ok(ctrl.config.builtins.keys().cloned().collect())
|
Ok(ctrl.config.builtins.keys().cloned().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn supported_basic_zones(&self) -> Result<Vec<AuraZone>, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.supported_data.basic_zones.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn supported_power_zones(&self) -> Result<Vec<PowerZones>, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.supported_data.power_zones.clone())
|
||||||
|
}
|
||||||
|
|
||||||
/// The current mode data
|
/// The current mode data
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
|
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
Ok(ctrl.config.current_mode)
|
Ok(ctrl.config.current_mode)
|
||||||
@@ -94,7 +101,7 @@ impl CtrlAuraZbus {
|
|||||||
///
|
///
|
||||||
/// On success the aura config file is read to refresh cached values, then
|
/// On success the aura config file is read to refresh cached values, then
|
||||||
/// the effect is stored and config written to disk.
|
/// the effect is stored and config written to disk.
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
|
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.config.current_mode = num;
|
ctrl.config.current_mode = num;
|
||||||
@@ -102,14 +109,16 @@ impl CtrlAuraZbus {
|
|||||||
if ctrl.config.brightness == LedBrightness::Off {
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
ctrl.config.brightness = LedBrightness::Med;
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
}
|
}
|
||||||
ctrl.sysfs_node
|
ctrl.led_node
|
||||||
.set_brightness(ctrl.config.brightness.into())?;
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
|
self.led_mode_data_invalidate(&self.1).await.ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The current mode data
|
/// The current mode data
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
let mode = ctrl.config.current_mode;
|
let mode = ctrl.config.current_mode;
|
||||||
@@ -123,12 +132,12 @@ impl CtrlAuraZbus {
|
|||||||
///
|
///
|
||||||
/// On success the aura config file is read to refresh cached values, then
|
/// On success the aura config file is read to refresh cached values, then
|
||||||
/// the effect is stored and config written to disk.
|
/// the effect is stored and config written to disk.
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
|
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
if !ctrl.supported_modes.basic_modes.contains(&effect.mode)
|
if !ctrl.supported_data.basic_modes.contains(&effect.mode)
|
||||||
|| effect.zone != AuraZone::None
|
|| effect.zone != AuraZone::None
|
||||||
&& !ctrl.supported_modes.basic_zones.contains(&effect.zone)
|
&& !ctrl.supported_data.basic_zones.contains(&effect.zone)
|
||||||
{
|
{
|
||||||
return Err(ZbErr::NotSupported(format!(
|
return Err(ZbErr::NotSupported(format!(
|
||||||
"The Aura effect is not supported: {effect:?}"
|
"The Aura effect is not supported: {effect:?}"
|
||||||
@@ -139,10 +148,12 @@ impl CtrlAuraZbus {
|
|||||||
if ctrl.config.brightness == LedBrightness::Off {
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
ctrl.config.brightness = LedBrightness::Med;
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
}
|
}
|
||||||
ctrl.sysfs_node
|
ctrl.led_node
|
||||||
.set_brightness(ctrl.config.brightness.into())?;
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
ctrl.config.set_builtin(effect);
|
ctrl.config.set_builtin(effect);
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
|
self.led_mode_invalidate(&self.1).await.ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,28 +164,27 @@ impl CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn led_power(&self) -> AuraPowerDev {
|
async fn led_power(&self) -> LaptopAuraPower {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
AuraPowerDev::from(&ctrl.config.enabled)
|
ctrl.config.enabled.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a variety of states, input is array of enum.
|
/// Set a variety of states, input is array of enum.
|
||||||
/// `enabled` sets if the sent array should be disabled or enabled
|
/// `enabled` sets if the sent array should be disabled or enabled
|
||||||
///
|
///
|
||||||
/// For Modern ROG devices the "enabled" flag is ignored.
|
/// For Modern ROG devices the "enabled" flag is ignored.
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_led_power(&mut self, options: (AuraPowerDev, bool)) -> Result<(), ZbErr> {
|
async fn set_led_power(&mut self, options: LaptopAuraPower) -> Result<(), ZbErr> {
|
||||||
let enabled = options.1;
|
|
||||||
let options = options.0;
|
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
for p in options.tuf {
|
for opt in options.states {
|
||||||
ctrl.config.enabled.set_tuf(p, enabled);
|
let zone = opt.zone;
|
||||||
|
for config in ctrl.config.enabled.states.iter_mut() {
|
||||||
|
if config.zone == zone {
|
||||||
|
*config = opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for p in options.old_rog {
|
|
||||||
ctrl.config.enabled.set_0x1866(p, enabled);
|
|
||||||
}
|
|
||||||
ctrl.config.enabled.set_0x19b6(options.rog);
|
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
Ok(ctrl.set_power_states().map_err(|e| {
|
Ok(ctrl.set_power_states().map_err(|e| {
|
||||||
warn!("{}", e);
|
warn!("{}", e);
|
||||||
@@ -192,30 +202,35 @@ impl CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl CtrlTask for CtrlAuraZbus {
|
impl CtrlTask for CtrlAuraZbus {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
AURA_ZBUS_PATH
|
"/org/asuslinux"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let load_save = |start: bool, mut lock: MutexGuard<'_, CtrlKbdLed>| {
|
let load_save =
|
||||||
// If waking up
|
|start: bool, mut lock: MutexGuard<'_, CtrlKbdLed>| -> Result<(), RogError> {
|
||||||
if !start {
|
// If waking up
|
||||||
info!("CtrlKbdLedTask reloading brightness and modes");
|
if !start {
|
||||||
lock.sysfs_node
|
info!("CtrlKbdLedTask reloading brightness and modes");
|
||||||
.set_brightness(lock.config.brightness.into())
|
lock.led_node
|
||||||
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
.set_brightness(lock.config.brightness.into())
|
||||||
.ok();
|
.map_err(|e| {
|
||||||
lock.write_current_config_mode()
|
error!("CtrlKbdLedTask: {e}");
|
||||||
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
e
|
||||||
.ok();
|
})?;
|
||||||
} else if start {
|
lock.write_current_config_mode().map_err(|e| {
|
||||||
Self::update_config(&mut lock)
|
error!("CtrlKbdLedTask: {e}");
|
||||||
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
e
|
||||||
.ok();
|
})?;
|
||||||
}
|
} else if start {
|
||||||
};
|
Self::update_config(&mut lock).map_err(|e| {
|
||||||
|
error!("CtrlKbdLedTask: {e}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
let inner1 = self.0.clone();
|
let inner1 = self.0.clone();
|
||||||
let inner3 = self.0.clone();
|
let inner3 = self.0.clone();
|
||||||
@@ -224,14 +239,16 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
let inner1 = inner1.clone();
|
let inner1 = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner1.lock().await;
|
let lock = inner1.lock().await;
|
||||||
load_save(sleeping, lock);
|
load_save(sleeping, lock).unwrap(); // unwrap as we want to
|
||||||
|
// bomb out of the task
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move |_shutting_down| {
|
move |_shutting_down| {
|
||||||
let inner3 = inner3.clone();
|
let inner3 = inner3.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner3.lock().await;
|
let lock = inner3.lock().await;
|
||||||
load_save(false, lock);
|
load_save(false, lock).unwrap(); // unwrap as we want to
|
||||||
|
// bomb out of the task
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move |_lid_closed| {
|
move |_lid_closed| {
|
||||||
@@ -247,7 +264,7 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
|
|
||||||
let ctrl2 = self.0.clone();
|
let ctrl2 = self.0.clone();
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
let watch = ctrl.sysfs_node.monitor_brightness()?;
|
let watch = ctrl.led_node.monitor_brightness()?;
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
watch
|
watch
|
||||||
@@ -255,7 +272,8 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.for_each(|_| async {
|
.for_each(|_| async {
|
||||||
if let Some(lock) = ctrl2.try_lock() {
|
if let Some(lock) = ctrl2.try_lock() {
|
||||||
load_save(true, lock);
|
load_save(true, lock).unwrap(); // unwrap as we want to
|
||||||
|
// bomb out of the task
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -265,13 +283,12 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::Reloadable for CtrlAuraZbus {
|
impl crate::Reloadable for CtrlAuraZbus {
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
debug!("CtrlKbdLedZbus: reloading keyboard mode");
|
debug!("reloading keyboard mode");
|
||||||
ctrl.write_current_config_mode()?;
|
ctrl.write_current_config_mode()?;
|
||||||
debug!("CtrlKbdLedZbus: reloading power states");
|
debug!("reloading power states");
|
||||||
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+93
-120
@@ -1,30 +1,26 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use futures_lite::StreamExt;
|
use futures_lite::StreamExt;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::platform::{PlatformPolicy, RogPlatform};
|
use rog_platform::platform::{RogPlatform, ThrottlePolicy};
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
use rog_profiles::fan_curve_set::CurveData;
|
||||||
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
|
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{interface, Connection, SignalContext};
|
||||||
|
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::{CtrlTask, CONFIG_PATH_BASE};
|
use crate::{CtrlTask, CONFIG_PATH_BASE};
|
||||||
|
|
||||||
const MOD_NAME: &str = "FanCurveZbus";
|
|
||||||
pub const FAN_CURVE_ZBUS_NAME: &str = "FanCurves";
|
pub const FAN_CURVE_ZBUS_NAME: &str = "FanCurves";
|
||||||
pub const FAN_CURVE_ZBUS_PATH: &str = "/org/asuslinux/FanCurves";
|
pub const FAN_CURVE_ZBUS_PATH: &str = "/org/asuslinux";
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
pub struct FanCurveConfig {
|
pub struct FanCurveConfig {
|
||||||
pub balanced: Vec<CurveData>,
|
pub profiles: FanCurveProfiles,
|
||||||
pub performance: Vec<CurveData>,
|
|
||||||
pub quiet: Vec<CurveData>,
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub current: u8,
|
pub current: u8,
|
||||||
}
|
}
|
||||||
@@ -50,7 +46,6 @@ impl StdConfigLoad for FanCurveConfig {}
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CtrlFanCurveZbus {
|
pub struct CtrlFanCurveZbus {
|
||||||
config: Arc<Mutex<FanCurveConfig>>,
|
config: Arc<Mutex<FanCurveConfig>>,
|
||||||
fan_curves: Arc<Mutex<FanCurveProfiles>>,
|
|
||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,89 +54,71 @@ impl CtrlFanCurveZbus {
|
|||||||
pub fn new() -> Result<Self, RogError> {
|
pub fn new() -> Result<Self, RogError> {
|
||||||
let platform = RogPlatform::new()?;
|
let platform = RogPlatform::new()?;
|
||||||
if platform.has_throttle_thermal_policy() {
|
if platform.has_throttle_thermal_policy() {
|
||||||
info!("{MOD_NAME}: Device has profile control available");
|
info!("Device has profile control available");
|
||||||
find_fan_curve_node()?;
|
find_fan_curve_node()?;
|
||||||
info!("{MOD_NAME}: Device has fan curves available");
|
info!("Device has fan curves available");
|
||||||
let mut config = FanCurveConfig::new();
|
let mut config = FanCurveConfig::new().load();
|
||||||
let mut fan_curves = FanCurveProfiles::default();
|
let mut fan_curves = FanCurveProfiles::default();
|
||||||
|
|
||||||
// Only do defaults if the config doesn't already exist
|
// Only do defaults if the config doesn't already exist\
|
||||||
if !config.file_path().exists() {
|
if config.profiles.balanced.is_empty() || !config.file_path().exists() {
|
||||||
info!("{MOD_NAME}: Fetching default fan curves");
|
info!("Fetching default fan curves");
|
||||||
|
|
||||||
|
let current = platform.get_throttle_thermal_policy()?;
|
||||||
for this in [
|
for this in [
|
||||||
PlatformPolicy::Balanced,
|
ThrottlePolicy::Balanced,
|
||||||
PlatformPolicy::Performance,
|
ThrottlePolicy::Performance,
|
||||||
PlatformPolicy::Quiet,
|
ThrottlePolicy::Quiet,
|
||||||
] {
|
] {
|
||||||
// For each profile we need to switch to it before we
|
// For each profile we need to switch to it before we
|
||||||
// can read the existing values from hardware. The ACPI method used
|
// can read the existing values from hardware. The ACPI method used
|
||||||
// for this is what limits us.
|
// for this is what limits us.
|
||||||
let next = PlatformPolicy::get_next_profile(this);
|
platform.set_throttle_thermal_policy(this.into())?;
|
||||||
platform.set_throttle_thermal_policy(next.into())?;
|
let mut dev = find_fan_curve_node()?;
|
||||||
|
fan_curves.set_active_curve_to_defaults(this, &mut dev)?;
|
||||||
|
|
||||||
let active = platform
|
info!("{this:?}:");
|
||||||
.get_throttle_thermal_policy()
|
for curve in fan_curves.get_fan_curves_for(this) {
|
||||||
.map_or(PlatformPolicy::Balanced, |t| t.into());
|
|
||||||
|
|
||||||
info!("{MOD_NAME}: {active:?}:");
|
|
||||||
for curve in fan_curves.get_fan_curves_for(active) {
|
|
||||||
info!("{}", String::from(curve));
|
info!("{}", String::from(curve));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
platform.set_throttle_thermal_policy(current)?;
|
||||||
|
config.profiles = fan_curves;
|
||||||
config.write();
|
config.write();
|
||||||
} else {
|
} else {
|
||||||
info!("{MOD_NAME}: Fan curves previously stored, loading...");
|
info!("Fan curves previously stored, loading...");
|
||||||
config = config.load();
|
config = config.load();
|
||||||
fan_curves.balanced = config.balanced.clone();
|
|
||||||
fan_curves.performance = config.performance.clone();
|
|
||||||
fan_curves.quiet = config.quiet.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
config: Arc::new(Mutex::new(config)),
|
config: Arc::new(Mutex::new(config)),
|
||||||
fan_curves: Arc::new(Mutex::new(fan_curves)),
|
|
||||||
platform,
|
platform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(ProfileError::NotSupported.into())
|
Err(ProfileError::NotSupported.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_profiles_from_config(&self) {
|
|
||||||
self.fan_curves.lock().await.balanced = self.config.lock().await.balanced.clone();
|
|
||||||
self.fan_curves.lock().await.performance = self.config.lock().await.performance.clone();
|
|
||||||
self.fan_curves.lock().await.quiet = self.config.lock().await.quiet.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Because this locks both config and fan_curves, it means nothing else can
|
|
||||||
/// hold a lock across this function call. Stupid choice to do this and
|
|
||||||
/// needs to be fixed.
|
|
||||||
pub async fn update_config_from_profiles(&self) {
|
|
||||||
self.config.lock().await.balanced = self.fan_curves.lock().await.balanced.clone();
|
|
||||||
self.config.lock().await.performance = self.fan_curves.lock().await.performance.clone();
|
|
||||||
self.config.lock().await.quiet = self.fan_curves.lock().await.quiet.clone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[interface(name = "org.asuslinux.FanCurves")]
|
||||||
impl CtrlFanCurveZbus {
|
impl CtrlFanCurveZbus {
|
||||||
/// Set all fan curves for a profile to enabled status. Will also activate a
|
/// Set all fan curves for a profile to enabled status. Will also activate a
|
||||||
/// fan curve if in the same profile mode
|
/// fan curve if in the same profile mode
|
||||||
async fn set_fan_curves_enabled(
|
async fn set_fan_curves_enabled(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformPolicy,
|
profile: ThrottlePolicy,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.fan_curves
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.set_profile_curves_enabled(profile, enabled);
|
.set_profile_curves_enabled(profile, enabled);
|
||||||
self.fan_curves
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
self.update_config_from_profiles().await;
|
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -150,32 +127,34 @@ impl CtrlFanCurveZbus {
|
|||||||
/// activate a fan curve if in the same profile mode
|
/// activate a fan curve if in the same profile mode
|
||||||
async fn set_profile_fan_curve_enabled(
|
async fn set_profile_fan_curve_enabled(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformPolicy,
|
profile: ThrottlePolicy,
|
||||||
fan: FanCurvePU,
|
fan: FanCurvePU,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.fan_curves
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.set_profile_fan_curve_enabled(profile, fan, enabled);
|
.set_profile_fan_curve_enabled(profile, fan, enabled);
|
||||||
self.fan_curves
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
self.update_config_from_profiles().await;
|
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the fan-curve data for the currently active PlatformPolicy
|
/// Get the fan-curve data for the currently active ThrottlePolicy
|
||||||
async fn fan_curve_data(
|
async fn fan_curve_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformPolicy,
|
profile: ThrottlePolicy,
|
||||||
) -> zbus::fdo::Result<Vec<CurveData>> {
|
) -> zbus::fdo::Result<Vec<CurveData>> {
|
||||||
let curve = self
|
let curve = self
|
||||||
.fan_curves
|
.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.get_fan_curves_for(profile)
|
.get_fan_curves_for(profile)
|
||||||
.to_vec();
|
.to_vec();
|
||||||
Ok(curve)
|
Ok(curve)
|
||||||
@@ -185,72 +164,71 @@ impl CtrlFanCurveZbus {
|
|||||||
/// Will also activate the fan curve if the user is in the same mode.
|
/// Will also activate the fan curve if the user is in the same mode.
|
||||||
async fn set_fan_curve(
|
async fn set_fan_curve(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformPolicy,
|
profile: ThrottlePolicy,
|
||||||
curve: CurveData,
|
curve: CurveData,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.fan_curves
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.save_fan_curve(curve, profile)?;
|
.save_fan_curve(curve, profile)?;
|
||||||
self.fan_curves
|
let active: ThrottlePolicy = self.platform.get_throttle_thermal_policy()?.into();
|
||||||
.lock()
|
if active == profile {
|
||||||
.await
|
self.config
|
||||||
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
|
||||||
self.update_config_from_profiles().await;
|
|
||||||
self.config.lock().await.write();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the stored (self) and device curve to the defaults of the
|
|
||||||
/// platform.
|
|
||||||
///
|
|
||||||
/// Each platform_profile has a different default and the defualt can be
|
|
||||||
/// read only for the currently active profile.
|
|
||||||
async fn set_active_curve_to_defaults(&mut self) -> zbus::fdo::Result<()> {
|
|
||||||
let active = self.platform.get_throttle_thermal_policy()?;
|
|
||||||
self.fan_curves
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.set_active_curve_to_defaults(active.into(), &mut find_fan_curve_node()?)?;
|
|
||||||
self.update_config_from_profiles().await;
|
|
||||||
self.config.lock().await.write();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the stored (self) and device curve to the defaults of the
|
|
||||||
/// platform.
|
|
||||||
///
|
|
||||||
/// Each platform_profile has a different default and the defualt can be
|
|
||||||
/// read only for the currently active profile.
|
|
||||||
async fn reset_profile_curves(&self, profile: PlatformPolicy) -> zbus::fdo::Result<()> {
|
|
||||||
let active = self
|
|
||||||
.platform
|
|
||||||
.get_throttle_thermal_policy()
|
|
||||||
.unwrap_or(PlatformPolicy::Balanced.into());
|
|
||||||
|
|
||||||
self.platform.set_throttle_thermal_policy(profile.into())?;
|
|
||||||
{
|
|
||||||
self.fan_curves
|
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.set_active_curve_to_defaults(active.into(), &mut find_fan_curve_node()?)?;
|
.profiles
|
||||||
|
.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
}
|
}
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the stored (self) and device curves to the defaults of the
|
||||||
|
/// platform.
|
||||||
|
///
|
||||||
|
/// Each platform_profile has a different default and the default can be
|
||||||
|
/// read only for the currently active profile.
|
||||||
|
async fn set_curves_to_defaults(&mut self, profile: ThrottlePolicy) -> zbus::fdo::Result<()> {
|
||||||
|
let active = self.platform.get_throttle_thermal_policy()?;
|
||||||
|
self.platform.set_throttle_thermal_policy(profile.into())?;
|
||||||
|
self.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.profiles
|
||||||
|
.set_active_curve_to_defaults(profile, &mut find_fan_curve_node()?)?;
|
||||||
|
self.platform.set_throttle_thermal_policy(active)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the stored (self) and device curve to the defaults of the
|
||||||
|
/// platform.
|
||||||
|
///
|
||||||
|
/// Each platform_profile has a different default and the defualt can be
|
||||||
|
/// read only for the currently active profile.
|
||||||
|
async fn reset_profile_curves(&self, profile: ThrottlePolicy) -> zbus::fdo::Result<()> {
|
||||||
|
let active = self.platform.get_throttle_thermal_policy()?;
|
||||||
|
|
||||||
|
self.platform.set_throttle_thermal_policy(profile.into())?;
|
||||||
|
self.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.profiles
|
||||||
|
.set_active_curve_to_defaults(active.into(), &mut find_fan_curve_node()?)?;
|
||||||
self.platform.set_throttle_thermal_policy(active)?;
|
self.platform.set_throttle_thermal_policy(active)?;
|
||||||
|
|
||||||
self.update_config_from_profiles().await;
|
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for CtrlFanCurveZbus {
|
impl crate::ZbusRun for CtrlFanCurveZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, FAN_CURVE_ZBUS_PATH, server).await;
|
Self::add_to_server_helper(self, FAN_CURVE_ZBUS_PATH, server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl CtrlTask for CtrlFanCurveZbus {
|
impl CtrlTask for CtrlFanCurveZbus {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
FAN_CURVE_ZBUS_PATH
|
FAN_CURVE_ZBUS_PATH
|
||||||
@@ -260,7 +238,7 @@ impl CtrlTask for CtrlFanCurveZbus {
|
|||||||
let watch_throttle_thermal_policy = self.platform.monitor_throttle_thermal_policy()?;
|
let watch_throttle_thermal_policy = self.platform.monitor_throttle_thermal_policy()?;
|
||||||
let platform = self.platform.clone();
|
let platform = self.platform.clone();
|
||||||
let config = self.config.clone();
|
let config = self.config.clone();
|
||||||
let fan_curves = self.fan_curves.clone();
|
let fan_curves = self.config.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
@@ -268,25 +246,23 @@ impl CtrlTask for CtrlFanCurveZbus {
|
|||||||
while (stream.next().await).is_some() {
|
while (stream.next().await).is_some() {
|
||||||
debug!("watch_throttle_thermal_policy changed");
|
debug!("watch_throttle_thermal_policy changed");
|
||||||
if let Ok(profile) = platform.get_throttle_thermal_policy().map_err(|e| {
|
if let Ok(profile) = platform.get_throttle_thermal_policy().map_err(|e| {
|
||||||
error!("{MOD_NAME}: get_throttle_thermal_policy error: {e}");
|
error!("get_throttle_thermal_policy error: {e}");
|
||||||
}) {
|
}) {
|
||||||
if profile != config.lock().await.current {
|
if profile != config.lock().await.current {
|
||||||
fan_curves
|
fan_curves
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
.profiles
|
||||||
.write_profile_curve_to_platform(
|
.write_profile_curve_to_platform(
|
||||||
profile.into(),
|
profile.into(),
|
||||||
&mut find_fan_curve_node().unwrap(),
|
&mut find_fan_curve_node().unwrap(),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
||||||
warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e)
|
|
||||||
})
|
|
||||||
.ok();
|
.ok();
|
||||||
config.lock().await.current = profile;
|
config.lock().await.current = profile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg!("STREAM ENDED");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -294,20 +270,17 @@ impl CtrlTask for CtrlFanCurveZbus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::Reloadable for CtrlFanCurveZbus {
|
impl crate::Reloadable for CtrlFanCurveZbus {
|
||||||
/// Fetch the active profile and use that to set all related components up
|
/// Fetch the active profile and use that to set all related components up
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
// let active = self.platform.get_throttle_thermal_policy()?.into();
|
let active = self.platform.get_throttle_thermal_policy()?.into();
|
||||||
// if let Ok(mut device) = find_fan_curve_node() {
|
let mut config = self.config.lock().await;
|
||||||
// // There is a possibility that the curve was default zeroed, so this call
|
if let Ok(mut device) = find_fan_curve_node() {
|
||||||
// // initialises the data from system read and we need to save it
|
config
|
||||||
// // after
|
.profiles
|
||||||
// self.fan_curves
|
.write_profile_curve_to_platform(active, &mut device)?;
|
||||||
// .lock()
|
}
|
||||||
// .await
|
|
||||||
// .write_profile_curve_to_platform(active, &mut device)?;
|
|
||||||
// }
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+480
-168
@@ -1,24 +1,26 @@
|
|||||||
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::cpu::{CPUControl, CPUGovernor};
|
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||||
use rog_platform::platform::{GpuMode, PlatformPolicy, Properties, RogPlatform};
|
use rog_platform::platform::{GpuMode, Properties, RogPlatform, ThrottlePolicy};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::fdo::Error as FdoErr;
|
use zbus::fdo::Error as FdoErr;
|
||||||
use zbus::{dbus_interface, Connection, ObjectServer, SignalContext};
|
use zbus::{interface, Connection, ObjectServer, SignalContext};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_PATH};
|
use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_PATH};
|
||||||
use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_NAME, AURA_ZBUS_PATH};
|
use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_NAME, AURA_ZBUS_PATH};
|
||||||
use crate::ctrl_fancurves::{CtrlFanCurveZbus, FAN_CURVE_ZBUS_NAME, FAN_CURVE_ZBUS_PATH};
|
use crate::ctrl_fancurves::{CtrlFanCurveZbus, FAN_CURVE_ZBUS_NAME, FAN_CURVE_ZBUS_PATH};
|
||||||
|
use crate::ctrl_slash::trait_impls::{CtrlSlashZbus, SLASH_ZBUS_NAME, SLASH_ZBUS_PATH};
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::{task_watch_item, task_watch_item_notify, CtrlTask};
|
use crate::{task_watch_item, task_watch_item_notify, CtrlTask, ReloadAndNotify};
|
||||||
|
|
||||||
const ZBUS_PATH: &str = "/org/asuslinux/Platform";
|
const PLATFORM_ZBUS_NAME: &str = "Platform";
|
||||||
|
const PLATFORM_ZBUS_PATH: &str = "/org/asuslinux";
|
||||||
|
|
||||||
macro_rules! platform_get_value {
|
macro_rules! platform_get_value {
|
||||||
($self:ident, $property:tt, $prop_name:literal) => {
|
($self:ident, $property:tt, $prop_name:literal) => {
|
||||||
@@ -28,33 +30,18 @@ macro_rules! platform_get_value {
|
|||||||
$self.platform
|
$self.platform
|
||||||
.get()
|
.get()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("RogPlatform: {}: {}", $prop_name, err);
|
warn!("{}: {}", $prop_name, err);
|
||||||
FdoErr::Failed(format!("RogPlatform: {}: {}", $prop_name, err))
|
FdoErr::Failed(format!("RogPlatform: {}: {}", $prop_name, err))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
error!("RogPlatform: {} not supported", $prop_name);
|
|
||||||
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! platform_get_value_if_some {
|
macro_rules! platform_set_value {
|
||||||
($self:ident, $property:tt, $prop_name:literal, $default:expr) => {
|
|
||||||
concat_idents::concat_idents!(has = has_, $property {
|
|
||||||
if $self.platform.has() {
|
|
||||||
let lock = $self.config.lock().await;
|
|
||||||
Ok(lock.ppt_pl1_spl.unwrap_or($default))
|
|
||||||
} else {
|
|
||||||
error!("RogPlatform: {} not supported", $prop_name);
|
|
||||||
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! platform_set_bool {
|
|
||||||
($self:ident, $property:tt, $prop_name:literal, $new_value:expr) => {
|
($self:ident, $property:tt, $prop_name:literal, $new_value:expr) => {
|
||||||
concat_idents::concat_idents!(has = has_, $property {
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
if $self.platform.has() {
|
if $self.platform.has() {
|
||||||
@@ -69,40 +56,32 @@ macro_rules! platform_set_bool {
|
|||||||
lock.write();
|
lock.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
error!("RogPlatform: {} not supported", $prop_name);
|
debug!("RogPlatform: {} not supported", $prop_name);
|
||||||
Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)))
|
Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Intended only for setting platform object values where the value isn't
|
macro_rules! platform_ppt_set_value {
|
||||||
/// retained across boots
|
($self:ident, $property:tt, $prop_name:literal, $new_value:expr) => {
|
||||||
macro_rules! platform_set_with_min_max {
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
($self:ident, $property:tt, $prop_name:literal, $new_value:expr, $min_value:expr, $max_value:expr) => {
|
if $self.platform.has() {
|
||||||
if !($min_value..=$max_value).contains(&$new_value) {
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
Err(FdoErr::Failed(
|
$self.platform.set($new_value).map_err(|err| {
|
||||||
format!("RogPlatform: {} value not in range {}=..={}", $prop_name, $min_value, $max_value)
|
error!("RogPlatform: {} {err}", $prop_name);
|
||||||
))
|
FdoErr::NotSupported(format!("RogPlatform: {} {err}", $prop_name))
|
||||||
} else {
|
})?;
|
||||||
concat_idents::concat_idents!(has = has_, $property {
|
});
|
||||||
if $self.platform.has() {
|
let mut lock = $self.config.lock().await;
|
||||||
concat_idents::concat_idents!(set = set_, $property {
|
lock.$property = Some($new_value);
|
||||||
$self.platform.set($new_value).map_err(|err| {
|
lock.write();
|
||||||
error!("RogPlatform: {} {err}", $prop_name);
|
Ok(())
|
||||||
FdoErr::NotSupported(format!("RogPlatform: {} {err}", $prop_name))
|
} else {
|
||||||
})?;
|
debug!("RogPlatform: ppt: setting {} not supported", $prop_name);
|
||||||
});
|
Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)))
|
||||||
let mut lock = $self.config.lock().await;
|
}
|
||||||
lock.$property = Some($new_value);
|
})
|
||||||
lock.write();
|
|
||||||
} else {
|
|
||||||
error!("RogPlatform: {} not supported", $prop_name);
|
|
||||||
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +94,11 @@ pub struct CtrlPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
pub fn new(
|
||||||
|
config: Arc<Mutex<Config>>,
|
||||||
|
config_path: &Path,
|
||||||
|
signal_context: SignalContext<'static>,
|
||||||
|
) -> Result<Self, RogError> {
|
||||||
let platform = RogPlatform::new()?;
|
let platform = RogPlatform::new()?;
|
||||||
let power = AsusPower::new()?;
|
let power = AsusPower::new()?;
|
||||||
|
|
||||||
@@ -124,20 +107,76 @@ impl CtrlPlatform {
|
|||||||
info!("Standard graphics switching will still work.");
|
info!("Standard graphics switching will still work.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CtrlPlatform {
|
let config1 = config.clone();
|
||||||
|
let config_path = config_path.to_owned();
|
||||||
|
|
||||||
|
let ret_self = CtrlPlatform {
|
||||||
power,
|
power,
|
||||||
platform,
|
platform,
|
||||||
config,
|
config,
|
||||||
cpu_control: CPUControl::new()
|
cpu_control: CPUControl::new()
|
||||||
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
||||||
.ok(),
|
.ok(),
|
||||||
})
|
};
|
||||||
|
let mut inotify_self = ret_self.clone();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
use zbus::export::futures_util::StreamExt;
|
||||||
|
info!("Starting inotify watch for asusd config file");
|
||||||
|
|
||||||
|
let mut buffer = [0; 32];
|
||||||
|
loop {
|
||||||
|
// vi and vim do stupid shit causing the file watch to be removed
|
||||||
|
let inotify = inotify::Inotify::init().unwrap();
|
||||||
|
inotify
|
||||||
|
.watches()
|
||||||
|
.add(
|
||||||
|
&config_path,
|
||||||
|
inotify::WatchMask::MODIFY
|
||||||
|
| inotify::WatchMask::CLOSE_WRITE
|
||||||
|
| inotify::WatchMask::ATTRIB
|
||||||
|
| inotify::WatchMask::CREATE,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
if e.kind() == std::io::ErrorKind::NotFound {
|
||||||
|
error!("Not found: {:?}", config_path);
|
||||||
|
} else {
|
||||||
|
error!("Could not set asusd config inotify: {:?}", config_path);
|
||||||
|
}
|
||||||
|
e
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
let mut events = inotify.into_event_stream(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
while let Some(ev) = events.next().await {
|
||||||
|
if let Ok(ev) = ev {
|
||||||
|
if ev.mask == inotify::EventMask::IGNORED {
|
||||||
|
warn!(
|
||||||
|
"Something modified asusd.ron vi/vim style. Now need to reload \
|
||||||
|
inotify watch"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = config1.lock().await.read_new();
|
||||||
|
if let Some(new_cfg) = res {
|
||||||
|
inotify_self
|
||||||
|
.reload_and_notify(&signal_context, new_cfg)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(ret_self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> {
|
fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> {
|
||||||
self.platform.set_gpu_mux_mode(mode.to_mux_attr())?;
|
self.platform.set_gpu_mux_mode(mode.to_mux_attr())?;
|
||||||
// self.update_initramfs(enable)?;
|
// self.update_initramfs(enable)?;
|
||||||
if mode == GpuMode::Discrete {
|
if mode == GpuMode::Ultimate {
|
||||||
info!("Set system-level graphics mode: Dedicated Nvidia");
|
info!("Set system-level graphics mode: Dedicated Nvidia");
|
||||||
} else {
|
} else {
|
||||||
info!("Set system-level graphics mode: Optimus");
|
info!("Set system-level graphics mode: Optimus");
|
||||||
@@ -180,38 +219,66 @@ impl CtrlPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_and_set_epp(&self, profile: PlatformPolicy) {
|
fn check_and_set_epp(&self, enegy_pref: CPUEPP, change_epp: bool) {
|
||||||
info!("PlatformPolicy setting EPP");
|
if !change_epp {
|
||||||
|
info!("ThrottlePolicy unlinked from EPP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info!("ThrottlePolicy setting EPP");
|
||||||
if let Some(cpu) = self.cpu_control.as_ref() {
|
if let Some(cpu) = self.cpu_control.as_ref() {
|
||||||
if let Ok(epp) = cpu.get_available_epp() {
|
if let Ok(epp) = cpu.get_available_epp() {
|
||||||
debug!("Available EPP: {epp:?}");
|
debug!("Available EPP: {epp:?}");
|
||||||
if epp.contains(&profile.into()) {
|
if epp.contains(&enegy_pref) {
|
||||||
debug!("Setting {profile:?}");
|
debug!("Setting {enegy_pref:?}");
|
||||||
cpu.set_epp(profile.into()).ok();
|
cpu.set_epp(enegy_pref).ok();
|
||||||
} else if let Ok(gov) = cpu.get_governor() {
|
} else if let Ok(gov) = cpu.get_governor() {
|
||||||
if gov != CPUGovernor::Powersave {
|
if gov != CPUGovernor::Powersave {
|
||||||
warn!("powersave governor is not is use, you should use it.");
|
warn!("powersave governor is not is use, trying to set.");
|
||||||
|
cpu.set_governor(CPUGovernor::Powersave)
|
||||||
|
.map_err(|e| error!("couldn't set powersave: {e:?}"))
|
||||||
|
.ok();
|
||||||
|
if epp.contains(&enegy_pref) {
|
||||||
|
debug!("Setting {enegy_pref:?}");
|
||||||
|
cpu.set_epp(enegy_pref)
|
||||||
|
.map_err(|e| error!("couldn't set EPP: {e:?}"))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_policy_ac_or_bat(&self, power_plugged: bool) {
|
async fn get_config_epp_for_throttle(&self, throttle: ThrottlePolicy) -> CPUEPP {
|
||||||
let profile = if power_plugged {
|
match throttle {
|
||||||
self.config.lock().await.platform_policy_on_ac
|
ThrottlePolicy::Balanced => self.config.lock().await.throttle_balanced_epp,
|
||||||
|
ThrottlePolicy::Performance => self.config.lock().await.throttle_performance_epp,
|
||||||
|
ThrottlePolicy::Quiet => self.config.lock().await.throttle_quiet_epp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_policy_ac_or_bat(&self, power_plugged: bool, change_epp: bool) {
|
||||||
|
let throttle = if power_plugged {
|
||||||
|
self.config.lock().await.throttle_policy_on_ac
|
||||||
} else {
|
} else {
|
||||||
self.config.lock().await.platform_policy_on_battery
|
self.config.lock().await.throttle_policy_on_battery
|
||||||
};
|
};
|
||||||
|
debug!("Setting {throttle:?} before EPP");
|
||||||
|
let epp = self.get_config_epp_for_throttle(throttle).await;
|
||||||
self.platform
|
self.platform
|
||||||
.set_throttle_thermal_policy(profile.into())
|
.set_throttle_thermal_policy(throttle.into())
|
||||||
.ok();
|
.ok();
|
||||||
self.check_and_set_epp(profile);
|
self.check_and_set_epp(epp, change_epp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[interface(name = "org.asuslinux.Platform")]
|
||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn version(&self) -> String {
|
||||||
|
crate::VERSION.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a list of property names that this system supports
|
/// Returns a list of property names that this system supports
|
||||||
async fn supported_properties(&self) -> Vec<Properties> {
|
async fn supported_properties(&self) -> Vec<Properties> {
|
||||||
let mut supported = Vec::new();
|
let mut supported = Vec::new();
|
||||||
@@ -244,11 +311,11 @@ impl CtrlPlatform {
|
|||||||
|
|
||||||
platform_name!(dgpu_disable, Properties::DgpuDisable);
|
platform_name!(dgpu_disable, Properties::DgpuDisable);
|
||||||
platform_name!(gpu_mux_mode, Properties::GpuMuxMode);
|
platform_name!(gpu_mux_mode, Properties::GpuMuxMode);
|
||||||
platform_name!(post_animation_sound, Properties::PostAnimationSound);
|
platform_name!(boot_sound, Properties::PostAnimationSound);
|
||||||
platform_name!(panel_od, Properties::PanelOd);
|
platform_name!(panel_od, Properties::PanelOd);
|
||||||
platform_name!(mini_led_mode, Properties::MiniLedMode);
|
platform_name!(mini_led_mode, Properties::MiniLedMode);
|
||||||
platform_name!(egpu_enable, Properties::EgpuEnable);
|
platform_name!(egpu_enable, Properties::EgpuEnable);
|
||||||
platform_name!(throttle_thermal_policy, Properties::PlatformPolicy);
|
platform_name!(throttle_thermal_policy, Properties::ThrottlePolicy);
|
||||||
|
|
||||||
platform_name!(ppt_pl1_spl, Properties::PptPl1Spl);
|
platform_name!(ppt_pl1_spl, Properties::PptPl1Spl);
|
||||||
platform_name!(ppt_pl2_sppt, Properties::PptPl2Sppt);
|
platform_name!(ppt_pl2_sppt, Properties::PptPl2Sppt);
|
||||||
@@ -287,45 +354,62 @@ impl CtrlPlatform {
|
|||||||
{
|
{
|
||||||
interfaces.push(FAN_CURVE_ZBUS_NAME.to_owned());
|
interfaces.push(FAN_CURVE_ZBUS_NAME.to_owned());
|
||||||
}
|
}
|
||||||
|
if server
|
||||||
|
.interface::<_, CtrlPlatform>(PLATFORM_ZBUS_PATH)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
interfaces.push(PLATFORM_ZBUS_NAME.to_owned());
|
||||||
|
}
|
||||||
|
if server
|
||||||
|
.interface::<_, CtrlSlashZbus>(SLASH_ZBUS_PATH)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
interfaces.push(SLASH_ZBUS_NAME.to_owned());
|
||||||
|
}
|
||||||
interfaces
|
interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
||||||
let limit = self.power.get_charge_control_end_threshold()?;
|
let limit = self.power.get_charge_control_end_threshold()?;
|
||||||
Ok(limit)
|
Ok(limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
||||||
if !(20..=100).contains(&limit) {
|
if !(20..=100).contains(&limit) {
|
||||||
return Err(RogError::ChargeLimit(limit))?;
|
return Err(RogError::ChargeLimit(limit))?;
|
||||||
}
|
}
|
||||||
self.power.set_charge_control_end_threshold(limit)?;
|
self.power.set_charge_control_end_threshold(limit)?;
|
||||||
self.config.lock().await.charge_control_end_threshold = limit;
|
self.config.lock().await.charge_control_end_threshold = limit;
|
||||||
|
self.config.lock().await.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
|
fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
|
||||||
self.platform.get_gpu_mux_mode().map_err(|err| {
|
self.platform.get_gpu_mux_mode().map_err(|err| {
|
||||||
warn!("RogPlatform: set_gpu_mux_mode {err}");
|
warn!("get_gpu_mux_mode {err}");
|
||||||
FdoErr::NotSupported("RogPlatform: set_gpu_mux_mode not supported".to_owned())
|
FdoErr::NotSupported("RogPlatform: set_gpu_mux_mode not supported".to_owned())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> {
|
async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> {
|
||||||
if self.platform.has_gpu_mux_mode() {
|
if self.platform.has_gpu_mux_mode() {
|
||||||
self.set_gfx_mode(mode.into()).map_err(|err| {
|
self.set_gfx_mode(mode.into()).map_err(|err| {
|
||||||
warn!("RogPlatform: set_gpu_mux_mode {}", err);
|
warn!("set_gpu_mux_mode {}", err);
|
||||||
FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}"))
|
FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}"))
|
||||||
})
|
})?;
|
||||||
|
self.config.lock().await.write();
|
||||||
} else {
|
} else {
|
||||||
Err(FdoErr::NotSupported(
|
return Err(FdoErr::NotSupported(
|
||||||
"RogPlatform: set_gpu_mux_mode not supported".to_owned(),
|
"RogPlatform: set_gpu_mux_mode not supported".to_owned(),
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
||||||
@@ -334,20 +418,21 @@ impl CtrlPlatform {
|
|||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
) -> Result<(), FdoErr> {
|
) -> Result<(), FdoErr> {
|
||||||
let policy: PlatformPolicy =
|
let policy: ThrottlePolicy =
|
||||||
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
||||||
.map(|n| n.into())?;
|
.map(|n| n.into())?;
|
||||||
let policy = PlatformPolicy::next(&policy);
|
let policy = ThrottlePolicy::next(policy);
|
||||||
|
|
||||||
if self.platform.has_throttle_thermal_policy() {
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
self.check_and_set_epp(policy);
|
let change_epp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
let epp = self.get_config_epp_for_throttle(policy).await;
|
||||||
|
self.check_and_set_epp(epp, change_epp);
|
||||||
self.platform
|
self.platform
|
||||||
.set_throttle_thermal_policy(policy.into())
|
.set_throttle_thermal_policy(policy.into())
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("RogPlatform: throttle_thermal_policy {}", err);
|
warn!("throttle_thermal_policy {}", err);
|
||||||
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
||||||
})?;
|
})?;
|
||||||
self.config.lock().await.platform_policy_to_restore = policy;
|
|
||||||
Ok(self.throttle_thermal_policy_changed(&ctxt).await?)
|
Ok(self.throttle_thermal_policy_changed(&ctxt).await?)
|
||||||
} else {
|
} else {
|
||||||
Err(FdoErr::NotSupported(
|
Err(FdoErr::NotSupported(
|
||||||
@@ -356,22 +441,24 @@ impl CtrlPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn throttle_thermal_policy(&self) -> Result<PlatformPolicy, FdoErr> {
|
fn throttle_thermal_policy(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||||
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
||||||
.map(|n| n.into())
|
.map(|n| n.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_throttle_thermal_policy(&mut self, policy: PlatformPolicy) -> Result<(), FdoErr> {
|
async fn set_throttle_thermal_policy(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
|
||||||
// TODO: watch for external changes
|
// TODO: watch for external changes
|
||||||
if self.platform.has_throttle_thermal_policy() {
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
self.check_and_set_epp(policy);
|
let change_epp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
self.config.lock().await.platform_policy_to_restore = policy;
|
let epp = self.get_config_epp_for_throttle(policy).await;
|
||||||
|
self.check_and_set_epp(epp, change_epp);
|
||||||
|
self.config.lock().await.write();
|
||||||
self.platform
|
self.platform
|
||||||
.set_throttle_thermal_policy(policy.into())
|
.set_throttle_thermal_policy(policy.into())
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("RogPlatform: throttle_thermal_policy {}", err);
|
warn!("throttle_thermal_policy {}", err);
|
||||||
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -381,150 +468,362 @@ impl CtrlPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn post_animation_sound(&self) -> Result<bool, FdoErr> {
|
async fn throttle_policy_linked_epp(&self) -> Result<bool, FdoErr> {
|
||||||
platform_get_value!(self, post_animation_sound, "post_animation_sound")
|
Ok(self.config.lock().await.throttle_policy_linked_epp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> {
|
async fn set_throttle_policy_linked_epp(&self, linked: bool) -> Result<(), zbus::Error> {
|
||||||
if self.platform.has_post_animation_sound() {
|
self.config.lock().await.throttle_policy_linked_epp = linked;
|
||||||
self.platform.set_post_animation_sound(on).map_err(|err| {
|
self.config.lock().await.write();
|
||||||
warn!("RogPlatform: set_post_animation_sound {}", err);
|
Ok(())
|
||||||
FdoErr::Failed(format!("RogPlatform: set_post_animation_sound: {err}"))
|
}
|
||||||
})
|
|
||||||
} else {
|
#[zbus(property)]
|
||||||
Err(FdoErr::NotSupported(
|
async fn throttle_policy_on_battery(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||||
"RogPlatform: set_post_animation_sound not supported".to_owned(),
|
Ok(self.config.lock().await.throttle_policy_on_battery)
|
||||||
))
|
}
|
||||||
}
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_throttle_policy_on_battery(
|
||||||
|
&mut self,
|
||||||
|
policy: ThrottlePolicy,
|
||||||
|
) -> Result<(), FdoErr> {
|
||||||
|
self.config.lock().await.throttle_policy_on_battery = policy;
|
||||||
|
self.set_throttle_thermal_policy(policy).await?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn throttle_policy_on_ac(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||||
|
Ok(self.config.lock().await.throttle_policy_on_ac)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_throttle_policy_on_ac(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
|
||||||
|
self.config.lock().await.throttle_policy_on_ac = policy;
|
||||||
|
self.set_throttle_thermal_policy(policy).await?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The energy_performance_preference for the quiet throttle/platform
|
||||||
|
/// profile
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn throttle_quiet_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||||
|
Ok(self.config.lock().await.throttle_quiet_epp)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_throttle_quiet_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||||
|
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
self.config.lock().await.throttle_quiet_epp = epp;
|
||||||
|
self.check_and_set_epp(epp, change_pp);
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The energy_performance_preference for the balanced throttle/platform
|
||||||
|
/// profile
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn throttle_balanced_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||||
|
Ok(self.config.lock().await.throttle_balanced_epp)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_throttle_balanced_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||||
|
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
self.config.lock().await.throttle_balanced_epp = epp;
|
||||||
|
self.check_and_set_epp(epp, change_pp);
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The energy_performance_preference for the performance throttle/platform
|
||||||
|
/// profile
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn throttle_performance_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||||
|
Ok(self.config.lock().await.throttle_performance_epp)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_throttle_performance_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||||
|
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
self.config.lock().await.throttle_performance_epp = epp;
|
||||||
|
self.check_and_set_epp(epp, change_pp);
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||||
/// internal config also.
|
/// internal config also.
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn panel_od(&self) -> Result<bool, FdoErr> {
|
fn panel_od(&self) -> Result<bool, FdoErr> {
|
||||||
platform_get_value!(self, panel_od, "panel_od")
|
platform_get_value!(self, panel_od, "panel_od")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
|
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
|
||||||
platform_set_bool!(self, panel_od, "panel_od", overdrive)
|
platform_set_value!(self, panel_od, "panel_od", overdrive)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the `boot_sound` value from platform. Updates the stored value in
|
||||||
|
/// internal config also.
|
||||||
|
#[zbus(property)]
|
||||||
|
fn boot_sound(&self) -> Result<bool, FdoErr> {
|
||||||
|
platform_get_value!(self, boot_sound, "boot_sound")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_boot_sound(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||||
|
platform_set_value!(self, boot_sound, "boot_sound", on)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||||
/// internal config also.
|
/// internal config also.
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn mini_led_mode(&self) -> Result<bool, FdoErr> {
|
fn mini_led_mode(&self) -> Result<bool, FdoErr> {
|
||||||
platform_get_value!(self, mini_led_mode, "mini_led_mode")
|
platform_get_value!(self, mini_led_mode, "mini_led_mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
|
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||||
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)
|
platform_set_value!(self, mini_led_mode, "mini_led_mode", on)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn dgpu_disable(&self) -> Result<bool, FdoErr> {
|
fn dgpu_disable(&self) -> Result<bool, FdoErr> {
|
||||||
platform_get_value!(self, dgpu_disable, "dgpu_disable")
|
platform_get_value!(self, dgpu_disable, "dgpu_disable")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
fn egpu_enable(&self) -> Result<bool, FdoErr> {
|
fn egpu_enable(&self) -> Result<bool, FdoErr> {
|
||||||
platform_get_value!(self, egpu_enable, "egpu_enable")
|
platform_get_value!(self, egpu_enable, "egpu_enable")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ************************************************************************
|
/// ***********************************************************************
|
||||||
#[dbus_interface(property)]
|
/// Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
|
||||||
|
/// Shown on Intel+Nvidia or AMD+Nvidia based systems:
|
||||||
|
/// * min=5, max=250
|
||||||
|
#[zbus(property)]
|
||||||
async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
|
async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5)
|
platform_get_value!(self, ppt_pl1_spl, "ppt_pl1_spl")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)
|
platform_ppt_set_value!(self, ppt_pl1_spl, "ppt_pl1_spl", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
|
||||||
|
/// on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
|
||||||
|
/// * min=5, max=250
|
||||||
|
#[zbus(property)]
|
||||||
async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
|
async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, ppt_pl2_sppt, "ppt_pl2_sppt", 5)
|
platform_get_value!(self, ppt_pl2_sppt, "ppt_pl2_sppt")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250)
|
platform_ppt_set_value!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
|
||||||
|
/// * min=5, max=250
|
||||||
|
#[zbus(property)]
|
||||||
async fn ppt_fppt(&self) -> Result<u8, FdoErr> {
|
async fn ppt_fppt(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, ppt_fppt, "ppt_fppt", 5)
|
platform_get_value!(self, ppt_fppt, "ppt_fppt")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250)
|
platform_ppt_set_value!(self, ppt_fppt, "ppt_fppt", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the APU SPPT limit. Shown on full AMD systems only:
|
||||||
|
/// * min=5, max=130
|
||||||
|
#[zbus(property)]
|
||||||
async fn ppt_apu_sppt(&self) -> Result<u8, FdoErr> {
|
async fn ppt_apu_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, ppt_apu_sppt, "ppt_apu_sppt", 5)
|
platform_get_value!(self, ppt_apu_sppt, "ppt_apu_sppt")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130)
|
platform_ppt_set_value!(self, ppt_apu_sppt, "ppt_apu_sppt", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the platform SPPT limit. Shown on full AMD systems only:
|
||||||
|
/// * min=5, max=130
|
||||||
|
#[zbus(property)]
|
||||||
async fn ppt_platform_sppt(&self) -> Result<u8, FdoErr> {
|
async fn ppt_platform_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, ppt_platform_sppt, "ppt_platform_sppt", 5)
|
platform_get_value!(self, ppt_platform_sppt, "ppt_platform_sppt")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130)
|
platform_ppt_set_value!(self, ppt_platform_sppt, "ppt_platform_sppt", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the dynamic boost limit of the Nvidia dGPU:
|
||||||
|
/// * min=5, max=25
|
||||||
|
#[zbus(property)]
|
||||||
async fn nv_dynamic_boost(&self) -> Result<u8, FdoErr> {
|
async fn nv_dynamic_boost(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, nv_dynamic_boost, "nv_dynamic_boost", 5)
|
platform_get_value!(self, nv_dynamic_boost, "nv_dynamic_boost")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25)
|
platform_ppt_set_value!(self, nv_dynamic_boost, "nv_dynamic_boost", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
/// Set the target temperature limit of the Nvidia dGPU:
|
||||||
|
/// * min=75, max=87
|
||||||
|
#[zbus(property)]
|
||||||
async fn nv_temp_target(&self) -> Result<u8, FdoErr> {
|
async fn nv_temp_target(&self) -> Result<u8, FdoErr> {
|
||||||
platform_get_value_if_some!(self, nv_temp_target, "nv_temp_target", 5)
|
platform_get_value!(self, nv_temp_target, "nv_temp_target")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(property)]
|
#[zbus(property)]
|
||||||
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
|
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87)
|
platform_ppt_set_value!(self, nv_temp_target, "nv_temp_target", value)?;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for CtrlPlatform {
|
impl crate::ZbusRun for CtrlPlatform {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
Self::add_to_server_helper(self, PLATFORM_ZBUS_PATH, server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
impl ReloadAndNotify for CtrlPlatform {
|
||||||
impl crate::Reloadable for CtrlPlatform {
|
type Data = Config;
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
|
||||||
if self.platform.has_panel_od() {
|
async fn reload_and_notify(
|
||||||
self.platform
|
&mut self,
|
||||||
.set_panel_od(self.config.lock().await.panel_od)?;
|
signal_context: &SignalContext<'static>,
|
||||||
|
data: Self::Data,
|
||||||
|
) -> Result<(), RogError> {
|
||||||
|
let mut config = self.config.lock().await;
|
||||||
|
if *config != data {
|
||||||
|
info!("asusd.ron updated externally, reloading and updating internal copy");
|
||||||
|
|
||||||
|
if self.power.has_charge_control_end_threshold() {
|
||||||
|
self.power
|
||||||
|
.set_charge_control_end_threshold(data.charge_control_end_threshold)?;
|
||||||
|
self.charge_control_end_threshold_changed(signal_context)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.platform.has_throttle_thermal_policy()
|
||||||
|
&& config.throttle_policy_linked_epp != data.throttle_policy_linked_epp
|
||||||
|
{
|
||||||
|
// TODO: extra stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! reload_and_notify {
|
||||||
|
($property:tt, $prop_name:literal) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if self.platform.has() && config.$property != data.$property {
|
||||||
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
|
self.platform
|
||||||
|
.set(data.$property)?;});
|
||||||
|
concat_idents::concat_idents!(changed = $property, _changed {
|
||||||
|
self.changed(signal_context).await?;});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reload_and_notify!(mini_led_mode, "mini_led_mode");
|
||||||
|
reload_and_notify!(panel_od, "panel_od");
|
||||||
|
reload_and_notify!(boot_sound, "boot_sound");
|
||||||
|
// reload_and_notify!(throttle_thermal_policy, "throttle_thermal_policy");
|
||||||
|
|
||||||
|
macro_rules! ppt_reload_and_notify {
|
||||||
|
($property:tt, $prop_name:literal) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if self.platform.has() && config.$property != data.$property {
|
||||||
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
|
self.platform
|
||||||
|
.set(data.$property.unwrap_or_default())?;});
|
||||||
|
concat_idents::concat_idents!(changed = $property, _changed {
|
||||||
|
self.changed(signal_context).await?;});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ppt_reload_and_notify!(ppt_pl1_spl, "ppt_pl1_spl");
|
||||||
|
ppt_reload_and_notify!(ppt_pl2_sppt, "ppt_pl2_sppt");
|
||||||
|
ppt_reload_and_notify!(ppt_fppt, "ppt_fppt");
|
||||||
|
ppt_reload_and_notify!(ppt_apu_sppt, "ppt_apu_sppt");
|
||||||
|
ppt_reload_and_notify!(ppt_platform_sppt, "ppt_platform_sppt");
|
||||||
|
ppt_reload_and_notify!(nv_dynamic_boost, "nv_dynamic_boost");
|
||||||
|
ppt_reload_and_notify!(nv_temp_target, "nv_temp_target");
|
||||||
|
|
||||||
|
*config = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.platform.has_mini_led_mode() {
|
Ok(())
|
||||||
self.platform
|
}
|
||||||
.set_mini_led_mode(self.config.lock().await.mini_led_mode)?;
|
}
|
||||||
|
|
||||||
|
impl crate::Reloadable for CtrlPlatform {
|
||||||
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
|
macro_rules! reload {
|
||||||
|
($property:tt, $prop_name:literal) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if self.platform.has() {
|
||||||
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
|
self.platform
|
||||||
|
.set(self.config.lock().await.$property)?;});
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
reload!(mini_led_mode, "mini_led_mode");
|
||||||
|
reload!(panel_od, "panel_od");
|
||||||
|
reload!(boot_sound, "boot_sound");
|
||||||
|
|
||||||
|
macro_rules! ppt_reload {
|
||||||
|
($property:tt, $prop_name:literal) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if self.platform.has() {
|
||||||
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
|
self.platform
|
||||||
|
.set(self.config.lock().await.$property.unwrap_or_default())?;});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ppt_reload!(ppt_pl1_spl, "ppt_pl1_spl");
|
||||||
|
ppt_reload!(ppt_pl2_sppt, "ppt_pl2_sppt");
|
||||||
|
ppt_reload!(ppt_fppt, "ppt_fppt");
|
||||||
|
ppt_reload!(ppt_apu_sppt, "ppt_apu_sppt");
|
||||||
|
ppt_reload!(ppt_platform_sppt, "ppt_platform_sppt");
|
||||||
|
ppt_reload!(nv_dynamic_boost, "nv_dynamic_boost");
|
||||||
|
ppt_reload!(nv_temp_target, "nv_temp_target");
|
||||||
|
|
||||||
if self.power.has_charge_control_end_threshold() {
|
if self.power.has_charge_control_end_threshold() {
|
||||||
self.power.set_charge_control_end_threshold(
|
self.power.set_charge_control_end_threshold(
|
||||||
@@ -533,8 +832,11 @@ impl crate::Reloadable for CtrlPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(power_plugged) = self.power.get_online() {
|
if let Ok(power_plugged) = self.power.get_online() {
|
||||||
|
self.config.lock().await.last_power_plugged = power_plugged;
|
||||||
if self.platform.has_throttle_thermal_policy() {
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
self.update_policy_ac_or_bat(power_plugged > 0).await;
|
let change_epp = self.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
self.update_policy_ac_or_bat(power_plugged > 0, change_epp)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
self.run_ac_or_bat_cmd(power_plugged > 0).await;
|
self.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||||
}
|
}
|
||||||
@@ -550,7 +852,7 @@ impl CtrlPlatform {
|
|||||||
|
|
||||||
task_watch_item!(charge_control_end_threshold power);
|
task_watch_item!(charge_control_end_threshold power);
|
||||||
|
|
||||||
task_watch_item_notify!(post_animation_sound platform);
|
task_watch_item_notify!(boot_sound platform);
|
||||||
|
|
||||||
task_watch_item_notify!(dgpu_disable platform);
|
task_watch_item_notify!(dgpu_disable platform);
|
||||||
|
|
||||||
@@ -574,10 +876,9 @@ impl CtrlPlatform {
|
|||||||
task_watch_item_notify!(nv_temp_target platform);
|
task_watch_item_notify!(nv_temp_target platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl CtrlTask for CtrlPlatform {
|
impl CtrlTask for CtrlPlatform {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
ZBUS_PATH
|
PLATFORM_ZBUS_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
@@ -613,11 +914,18 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
if let Ok(power_plugged) = platform1.power.get_online() {
|
if let Ok(power_plugged) = platform1.power.get_online() {
|
||||||
if !sleeping && platform1.platform.has_throttle_thermal_policy() {
|
if platform1.config.lock().await.last_power_plugged != power_plugged {
|
||||||
platform1.update_policy_ac_or_bat(power_plugged > 0).await;
|
if !sleeping && platform1.platform.has_throttle_thermal_policy() {
|
||||||
}
|
let change_epp =
|
||||||
if !sleeping {
|
platform1.config.lock().await.throttle_policy_linked_epp;
|
||||||
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
platform1
|
||||||
|
.update_policy_ac_or_bat(power_plugged > 0, change_epp)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if !sleeping {
|
||||||
|
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||||
|
}
|
||||||
|
platform1.config.lock().await.last_power_plugged = power_plugged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -648,7 +956,10 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
// power change
|
// power change
|
||||||
async move {
|
async move {
|
||||||
if platform3.platform.has_throttle_thermal_policy() {
|
if platform3.platform.has_throttle_thermal_policy() {
|
||||||
platform3.update_policy_ac_or_bat(power_plugged).await;
|
let change_epp = platform3.config.lock().await.throttle_policy_linked_epp;
|
||||||
|
platform3
|
||||||
|
.update_policy_ac_or_bat(power_plugged, change_epp)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
platform3.run_ac_or_bat_cmd(power_plugged).await;
|
platform3.run_ac_or_bat_cmd(power_plugged).await;
|
||||||
}
|
}
|
||||||
@@ -669,7 +980,7 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
// NOTE: Can't have this as a watch because on a write to it, it reverts back to
|
// NOTE: Can't have this as a watch because on a write to it, it reverts back to
|
||||||
// booted-with value as it does not actually change until reboot.
|
// booted-with value as it does not actually change until reboot.
|
||||||
self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
||||||
self.watch_post_animation_sound(signal_ctxt.clone()).await?;
|
self.watch_boot_sound(signal_ctxt.clone()).await?;
|
||||||
|
|
||||||
self.watch_ppt_pl1_spl(signal_ctxt.clone()).await?;
|
self.watch_ppt_pl1_spl(signal_ctxt.clone()).await?;
|
||||||
self.watch_ppt_pl2_sppt(signal_ctxt.clone()).await?;
|
self.watch_ppt_pl2_sppt(signal_ctxt.clone()).await?;
|
||||||
@@ -692,13 +1003,14 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
if let Ok(profile) = ctrl
|
if let Ok(profile) = ctrl
|
||||||
.platform
|
.platform
|
||||||
.get_throttle_thermal_policy()
|
.get_throttle_thermal_policy()
|
||||||
.map(PlatformPolicy::from)
|
.map(ThrottlePolicy::from)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Platform: get_throttle_thermal_policy error: {e}");
|
error!("Platform: get_throttle_thermal_policy error: {e}");
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
ctrl.check_and_set_epp(profile);
|
let change_epp = ctrl.config.lock().await.throttle_policy_linked_epp;
|
||||||
ctrl.config.lock().await.platform_policy_to_restore = profile;
|
let epp = ctrl.get_config_epp_for_throttle(profile).await;
|
||||||
|
ctrl.check_and_set_epp(epp, change_epp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
|
use rog_slash::{DeviceState, SlashMode};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
const CONFIG_FILE: &str = "slash.ron";
|
||||||
|
|
||||||
|
/// Config for base system actions for the anime display
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct SlashConfig {
|
||||||
|
pub slash_enabled: bool,
|
||||||
|
pub slash_brightness: u8,
|
||||||
|
pub slash_interval: u8,
|
||||||
|
pub slash_mode: SlashMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SlashConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
SlashConfig {
|
||||||
|
slash_enabled: true,
|
||||||
|
slash_brightness: 255,
|
||||||
|
slash_interval: 0,
|
||||||
|
slash_mode: SlashMode::Bounce,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl StdConfig for SlashConfig {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> String {
|
||||||
|
CONFIG_FILE.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_dir() -> std::path::PathBuf {
|
||||||
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfigLoad for SlashConfig {}
|
||||||
|
|
||||||
|
impl From<&SlashConfig> for DeviceState {
|
||||||
|
fn from(config: &SlashConfig) -> Self {
|
||||||
|
DeviceState {
|
||||||
|
slash_enabled: config.slash_enabled,
|
||||||
|
slash_brightness: config.slash_brightness,
|
||||||
|
slash_interval: config.slash_interval,
|
||||||
|
slash_mode: config.slash_mode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
pub mod config;
|
||||||
|
pub mod trait_impls;
|
||||||
|
|
||||||
|
use rog_platform::hid_raw::HidRaw;
|
||||||
|
use rog_platform::usb_raw::USBRaw;
|
||||||
|
use rog_slash::error::SlashError;
|
||||||
|
use rog_slash::usb::{get_slash_type, pkt_set_mode, pkt_set_options, pkts_for_init};
|
||||||
|
use rog_slash::{SlashMode, SlashType};
|
||||||
|
|
||||||
|
use crate::ctrl_slash::config::SlashConfig;
|
||||||
|
use crate::error::RogError;
|
||||||
|
|
||||||
|
enum Node {
|
||||||
|
Usb(USBRaw),
|
||||||
|
Hid(HidRaw),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
pub fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
||||||
|
// TODO: map and pass on errors
|
||||||
|
match self {
|
||||||
|
Node::Usb(u) => {
|
||||||
|
u.write_bytes(message).ok();
|
||||||
|
}
|
||||||
|
Node::Hid(h) => {
|
||||||
|
h.write_bytes(message).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CtrlSlash {
|
||||||
|
// node: HidRaw,
|
||||||
|
node: Node,
|
||||||
|
config: SlashConfig,
|
||||||
|
// slash_type: SlashType,
|
||||||
|
// // set to force thread to exit
|
||||||
|
// thread_exit: Arc<AtomicBool>,
|
||||||
|
// // Set to false when the thread exits
|
||||||
|
// thread_running: Arc<AtomicBool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CtrlSlash {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(config: SlashConfig) -> Result<CtrlSlash, RogError> {
|
||||||
|
let slash_type = get_slash_type()?;
|
||||||
|
if matches!(slash_type, SlashType::Unknown | SlashType::Unsupported) {
|
||||||
|
return Err(RogError::Slash(SlashError::NoDevice));
|
||||||
|
}
|
||||||
|
|
||||||
|
let usb = USBRaw::new(rog_slash::usb::PROD_ID).ok();
|
||||||
|
let hid = HidRaw::new(rog_slash::usb::PROD_ID_STR).ok();
|
||||||
|
let node = if usb.is_some() {
|
||||||
|
unsafe { Node::Usb(usb.unwrap_unchecked()) }
|
||||||
|
} else if hid.is_some() {
|
||||||
|
unsafe { Node::Hid(hid.unwrap_unchecked()) }
|
||||||
|
} else {
|
||||||
|
return Err(RogError::NotSupported);
|
||||||
|
};
|
||||||
|
|
||||||
|
let ctrl = CtrlSlash {
|
||||||
|
node,
|
||||||
|
config,
|
||||||
|
// slash_type,
|
||||||
|
// thread_exit: Arc::new(AtomicBool::new(false)),
|
||||||
|
// thread_running: Arc::new(AtomicBool::new(false)),
|
||||||
|
};
|
||||||
|
ctrl.do_initialization()?;
|
||||||
|
|
||||||
|
Ok(ctrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_initialization(&self) -> Result<(), RogError> {
|
||||||
|
let init_packets = pkts_for_init();
|
||||||
|
self.node.write_bytes(&init_packets[0])?;
|
||||||
|
self.node.write_bytes(&init_packets[1])?;
|
||||||
|
|
||||||
|
// Apply config upon initialization
|
||||||
|
let option_packets = pkt_set_options(
|
||||||
|
self.config.slash_enabled,
|
||||||
|
self.config.slash_brightness,
|
||||||
|
self.config.slash_interval,
|
||||||
|
);
|
||||||
|
self.node.write_bytes(&option_packets)?;
|
||||||
|
|
||||||
|
let mode_packets = pkt_set_mode(self.config.slash_mode);
|
||||||
|
self.node.write_bytes(&mode_packets[0])?;
|
||||||
|
self.node.write_bytes(&mode_packets[1])?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_options(&self, enabled: bool, brightness: u8, interval: u8) -> Result<(), RogError> {
|
||||||
|
let command_packets = pkt_set_options(enabled, brightness, interval);
|
||||||
|
self.node.write_bytes(&command_packets)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_slash_mode(&self, slash_mode: SlashMode) -> Result<(), RogError> {
|
||||||
|
let command_packets = pkt_set_mode(slash_mode);
|
||||||
|
self.node.write_bytes(&command_packets[0])?;
|
||||||
|
self.node.write_bytes(&command_packets[1])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use config_traits::StdConfig;
|
||||||
|
use log::warn;
|
||||||
|
use rog_slash::usb::{pkt_set_mode, pkt_set_options};
|
||||||
|
use rog_slash::{DeviceState, SlashMode};
|
||||||
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
|
use zbus::{interface, Connection, SignalContext};
|
||||||
|
|
||||||
|
use crate::ctrl_slash::CtrlSlash;
|
||||||
|
use crate::error::RogError;
|
||||||
|
|
||||||
|
pub const SLASH_ZBUS_NAME: &str = "Slash";
|
||||||
|
pub const SLASH_ZBUS_PATH: &str = "/org/asuslinux";
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlSlashZbus(pub Arc<Mutex<CtrlSlash>>);
|
||||||
|
|
||||||
|
/// The struct with the main dbus methods requires this trait
|
||||||
|
impl crate::ZbusRun for CtrlSlashZbus {
|
||||||
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
|
Self::add_to_server_helper(self, SLASH_ZBUS_PATH, server).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[interface(name = "org.asuslinux.Slash")]
|
||||||
|
impl CtrlSlashZbus {
|
||||||
|
/// Get enabled or not
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn enabled(&self) -> bool {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.slash_enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set enabled true or false
|
||||||
|
async fn set_enabled(&self, enabled: bool) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
let brightness = if enabled && lock.config.slash_brightness == 0 {
|
||||||
|
0x88
|
||||||
|
} else {
|
||||||
|
lock.config.slash_brightness
|
||||||
|
};
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_options(
|
||||||
|
enabled,
|
||||||
|
brightness,
|
||||||
|
lock.config.slash_interval,
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::set_options {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.slash_enabled = enabled;
|
||||||
|
lock.config.slash_brightness = brightness;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get brightness level
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn brightness(&self) -> u8 {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.slash_brightness
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set brightness level
|
||||||
|
async fn set_brightness(&self, brightness: u8) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
let enabled = brightness > 0;
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_options(
|
||||||
|
enabled,
|
||||||
|
brightness,
|
||||||
|
lock.config.slash_interval,
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::set_options {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.slash_enabled = enabled;
|
||||||
|
lock.config.slash_brightness = brightness;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn interval(&self) -> u8 {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.slash_interval
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set interval between slash animations (0-255)
|
||||||
|
async fn set_interval(&self, interval: u8) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_options(
|
||||||
|
lock.config.slash_enabled,
|
||||||
|
lock.config.slash_brightness,
|
||||||
|
interval,
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::set_options {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.slash_interval = interval;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn slash_mode(&self) -> u8 {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.slash_interval
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set interval between slash animations (0-255)
|
||||||
|
async fn set_slash_mode(&self, slash_mode: SlashMode) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
|
||||||
|
let command_packets = pkt_set_mode(slash_mode);
|
||||||
|
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&command_packets[0])
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::set_options {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&command_packets[1])
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::set_options {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.slash_mode = slash_mode;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the device state as stored by asusd
|
||||||
|
// #[zbus(property)]
|
||||||
|
async fn device_state(&self) -> DeviceState {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
DeviceState::from(&lock.config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::CtrlTask for CtrlSlashZbus {
|
||||||
|
fn zbus_path() -> &'static str {
|
||||||
|
SLASH_ZBUS_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::Reloadable for CtrlSlashZbus {
|
||||||
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
-48
@@ -1,8 +1,6 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io::Write;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use ::zbus::export::futures_util::lock::Mutex;
|
use ::zbus::export::futures_util::lock::Mutex;
|
||||||
use ::zbus::Connection;
|
use ::zbus::Connection;
|
||||||
@@ -10,24 +8,25 @@ use asusd::config::Config;
|
|||||||
use asusd::ctrl_anime::config::AnimeConfig;
|
use asusd::ctrl_anime::config::AnimeConfig;
|
||||||
use asusd::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
use asusd::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
||||||
use asusd::ctrl_anime::CtrlAnime;
|
use asusd::ctrl_anime::CtrlAnime;
|
||||||
use asusd::ctrl_aura::controller::CtrlKbdLed;
|
use asusd::ctrl_aura::manager::AuraManager;
|
||||||
use asusd::ctrl_aura::trait_impls::CtrlAuraZbus;
|
|
||||||
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
||||||
use asusd::ctrl_platform::CtrlPlatform;
|
use asusd::ctrl_platform::CtrlPlatform;
|
||||||
use asusd::{print_board_info, CtrlTask, Reloadable, ZbusRun, DBUS_NAME};
|
use asusd::ctrl_slash::config::SlashConfig;
|
||||||
use config_traits::{StdConfig, StdConfigLoad2};
|
use asusd::ctrl_slash::trait_impls::CtrlSlashZbus;
|
||||||
use log::{error, info, warn};
|
use asusd::ctrl_slash::CtrlSlash;
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME};
|
||||||
use tokio::time::sleep;
|
use config_traits::{StdConfig, StdConfigLoad, StdConfigLoad2, StdConfigLoad3};
|
||||||
use zbus::SignalContext;
|
use log::{error, info};
|
||||||
|
use zbus::fdo::ObjectManager;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// console_subscriber::init();
|
||||||
let mut logger = env_logger::Builder::new();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.target(env_logger::Target::Stdout)
|
||||||
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
|
.format_timestamp(None)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let is_service = match env::var_os("IS_SERVICE") {
|
let is_service = match env::var_os("IS_SERVICE") {
|
||||||
@@ -46,6 +45,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
info!(" daemon v{}", asusd::VERSION);
|
info!(" daemon v{}", asusd::VERSION);
|
||||||
info!(" rog-anime v{}", rog_anime::VERSION);
|
info!(" rog-anime v{}", rog_anime::VERSION);
|
||||||
|
info!(" rog-slash v{}", rog_slash::VERSION);
|
||||||
info!(" rog-aura v{}", rog_aura::VERSION);
|
info!(" rog-aura v{}", rog_aura::VERSION);
|
||||||
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
||||||
info!("rog-platform v{}", rog_platform::VERSION);
|
info!("rog-platform v{}", rog_platform::VERSION);
|
||||||
@@ -62,22 +62,18 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// Start zbus server
|
// Start zbus server
|
||||||
let mut connection = Connection::system().await?;
|
let mut connection = Connection::system().await?;
|
||||||
|
connection
|
||||||
|
.object_server()
|
||||||
|
.at("/org/asuslinux", ObjectManager)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let config = Config::new().load();
|
let config = Config::new().load();
|
||||||
|
let cfg_path = config.file_path();
|
||||||
let config = Arc::new(Mutex::new(config));
|
let config = Arc::new(Mutex::new(config));
|
||||||
|
|
||||||
// supported.add_to_server(&mut connection).await;
|
// supported.add_to_server(&mut connection).await;
|
||||||
|
|
||||||
match CtrlPlatform::new(config.clone()) {
|
|
||||||
Ok(ctrl) => {
|
|
||||||
let sig_ctx = CtrlPlatform::signal_context(&connection)?;
|
|
||||||
start_tasks(ctrl, &mut connection, sig_ctx).await?;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
error!("CtrlPlatform: {}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match CtrlFanCurveZbus::new() {
|
match CtrlFanCurveZbus::new() {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let sig_ctx = CtrlFanCurveZbus::signal_context(&connection)?;
|
let sig_ctx = CtrlFanCurveZbus::signal_context(&connection)?;
|
||||||
@@ -88,6 +84,20 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match CtrlPlatform::new(
|
||||||
|
config.clone(),
|
||||||
|
&cfg_path,
|
||||||
|
CtrlPlatform::signal_context(&connection)?,
|
||||||
|
) {
|
||||||
|
Ok(ctrl) => {
|
||||||
|
let sig_ctx = CtrlPlatform::signal_context(&connection)?;
|
||||||
|
start_tasks(ctrl, &mut connection, sig_ctx).await?;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("CtrlPlatform: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match CtrlAnime::new(AnimeConfig::new().load()) {
|
match CtrlAnime::new(AnimeConfig::new().load()) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlAnimeZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlAnimeZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
@@ -99,44 +109,28 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let laptop = LaptopLedData::get_data();
|
match CtrlSlash::new(SlashConfig::new().load()) {
|
||||||
// CtrlKbdLed deviates from the config pattern above due to requiring a keyboard
|
|
||||||
// detection first
|
|
||||||
match CtrlKbdLed::new(laptop) {
|
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlAuraZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlSlashZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
|
// Currently, the Slash has no need for a loop watching power events, however,
|
||||||
|
// it could be cool to have the slash do some power-on/off animation
|
||||||
|
// (It has a built-in power on animation which plays when u plug in the power
|
||||||
|
// supply)
|
||||||
|
let sig_ctx = CtrlSlashZbus::signal_context(&connection)?;
|
||||||
start_tasks(zbus, &mut connection, sig_ctx).await?;
|
start_tasks(zbus, &mut connection, sig_ctx).await?;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Keyboard control: {}", err);
|
info!("AniMe control: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = AuraManager::new(connection.clone()).await?;
|
||||||
|
|
||||||
// Request dbus name after finishing initalizing all functions
|
// Request dbus name after finishing initalizing all functions
|
||||||
connection.request_name(DBUS_NAME).await?;
|
connection.request_name(DBUS_NAME).await?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// This is just a blocker to idle and ensure the reator reacts
|
// This is just a blocker to idle and ensure the reator reacts
|
||||||
sleep(Duration::from_millis(1000)).await;
|
connection.executor().tick().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_tasks<T>(
|
|
||||||
mut zbus: T,
|
|
||||||
connection: &mut Connection,
|
|
||||||
signal_ctx: SignalContext<'static>,
|
|
||||||
) -> Result<(), Box<dyn Error>>
|
|
||||||
where
|
|
||||||
T: ZbusRun + Reloadable + CtrlTask + Clone,
|
|
||||||
{
|
|
||||||
let task = zbus.clone();
|
|
||||||
|
|
||||||
zbus.reload()
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
|
||||||
zbus.add_to_server(connection).await;
|
|
||||||
|
|
||||||
task.create_tasks(signal_ctx).await.ok();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use config_traits::ron;
|
|||||||
use rog_anime::error::AnimeError;
|
use rog_anime::error::AnimeError;
|
||||||
use rog_platform::error::PlatformError;
|
use rog_platform::error::PlatformError;
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
|
use rog_slash::error::SlashError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RogError {
|
pub enum RogError {
|
||||||
@@ -31,6 +32,7 @@ pub enum RogError {
|
|||||||
NoAuraKeyboard,
|
NoAuraKeyboard,
|
||||||
NoAuraNode,
|
NoAuraNode,
|
||||||
Anime(AnimeError),
|
Anime(AnimeError),
|
||||||
|
Slash(SlashError),
|
||||||
Platform(PlatformError),
|
Platform(PlatformError),
|
||||||
SystemdUnitAction(String),
|
SystemdUnitAction(String),
|
||||||
SystemdUnitWaitTimeout(String),
|
SystemdUnitWaitTimeout(String),
|
||||||
@@ -72,6 +74,7 @@ impl fmt::Display for RogError {
|
|||||||
RogError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
|
RogError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
|
||||||
RogError::NoAuraNode => write!(f, "No Aura keyboard node found"),
|
RogError::NoAuraNode => write!(f, "No Aura keyboard node found"),
|
||||||
RogError::Anime(deets) => write!(f, "AniMe Matrix error: {}", deets),
|
RogError::Anime(deets) => write!(f, "AniMe Matrix error: {}", deets),
|
||||||
|
RogError::Slash(deets) => write!(f, "Slash error: {}", deets),
|
||||||
RogError::Platform(deets) => write!(f, "Asus Platform error: {}", deets),
|
RogError::Platform(deets) => write!(f, "Asus Platform error: {}", deets),
|
||||||
RogError::SystemdUnitAction(action) => {
|
RogError::SystemdUnitAction(action) => {
|
||||||
write!(f, "systemd unit action {} failed", action)
|
write!(f, "systemd unit action {} failed", action)
|
||||||
@@ -103,6 +106,12 @@ impl From<AnimeError> for RogError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SlashError> for RogError {
|
||||||
|
fn from(err: SlashError) -> Self {
|
||||||
|
RogError::Slash(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<PlatformError> for RogError {
|
impl From<PlatformError> for RogError {
|
||||||
fn from(err: PlatformError) -> Self {
|
fn from(err: PlatformError) -> Self {
|
||||||
RogError::Platform(err)
|
RogError::Platform(err)
|
||||||
|
|||||||
+111
-85
@@ -9,13 +9,14 @@ pub mod ctrl_aura;
|
|||||||
pub mod ctrl_fancurves;
|
pub mod ctrl_fancurves;
|
||||||
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
||||||
pub mod ctrl_platform;
|
pub mod ctrl_platform;
|
||||||
|
/// Control of Slash led bar
|
||||||
|
pub mod ctrl_slash;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
use futures_lite::stream::StreamExt;
|
use futures_lite::stream::StreamExt;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
@@ -51,7 +52,7 @@ pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
|||||||
/// task_watch_item!(panel_od platform);
|
/// task_watch_item!(panel_od platform);
|
||||||
/// task_watch_item!(gpu_mux_mode platform);
|
/// task_watch_item!(gpu_mux_mode platform);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```\
|
||||||
/// // TODO: this is kind of useless if it can't trigger some action
|
/// // TODO: this is kind of useless if it can't trigger some action
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! task_watch_item {
|
macro_rules! task_watch_item {
|
||||||
@@ -130,34 +131,43 @@ pub fn print_board_info() {
|
|||||||
info!("Board name: {}", dmi.board_name);
|
info!("Board name: {}", dmi.board_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
pub trait Reloadable {
|
pub trait Reloadable {
|
||||||
async fn reload(&mut self) -> Result<(), RogError>;
|
fn reload(&mut self) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
pub trait ReloadAndNotify {
|
||||||
pub trait ZbusRun {
|
type Data: Send;
|
||||||
async fn add_to_server(self, server: &mut Connection);
|
|
||||||
|
|
||||||
async fn add_to_server_helper(
|
fn reload_and_notify(
|
||||||
|
&mut self,
|
||||||
|
signal_context: &SignalContext<'static>,
|
||||||
|
data: Self::Data,
|
||||||
|
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ZbusRun {
|
||||||
|
fn add_to_server(self, server: &mut Connection) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn add_to_server_helper(
|
||||||
iface: impl zbus::Interface,
|
iface: impl zbus::Interface,
|
||||||
path: &str,
|
path: &str,
|
||||||
server: &mut Connection,
|
server: &mut Connection,
|
||||||
) {
|
) -> impl Future<Output = ()> + Send {
|
||||||
server
|
async move {
|
||||||
.object_server()
|
server
|
||||||
.at(&ObjectPath::from_str_unchecked(path), iface)
|
.object_server()
|
||||||
.await
|
.at(&ObjectPath::from_str_unchecked(path), iface)
|
||||||
.map_err(|err| {
|
.await
|
||||||
warn!("{}: add_to_server {}", path, err);
|
.map_err(|err| {
|
||||||
err
|
warn!("{}: add_to_server {}", path, err);
|
||||||
})
|
err
|
||||||
.ok();
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up a task to run on the async executor
|
/// Set up a task to run on the async executor
|
||||||
#[async_trait]
|
|
||||||
pub trait CtrlTask {
|
pub trait CtrlTask {
|
||||||
fn zbus_path() -> &'static str;
|
fn zbus_path() -> &'static str;
|
||||||
|
|
||||||
@@ -168,7 +178,10 @@ pub trait CtrlTask {
|
|||||||
/// Implement to set up various tasks that may be required, using the
|
/// Implement to set up various tasks that may be required, using the
|
||||||
/// `Executor`. No blocking loops are allowed, or they must be run on a
|
/// `Executor`. No blocking loops are allowed, or they must be run on a
|
||||||
/// separate thread.
|
/// separate thread.
|
||||||
async fn create_tasks(&self, signal: SignalContext<'static>) -> Result<(), RogError>;
|
fn create_tasks(
|
||||||
|
&self,
|
||||||
|
signal: SignalContext<'static>,
|
||||||
|
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||||
|
|
||||||
// /// Create a timed repeating task
|
// /// Create a timed repeating task
|
||||||
// async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send +
|
// async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send +
|
||||||
@@ -186,95 +199,89 @@ pub trait CtrlTask {
|
|||||||
///
|
///
|
||||||
/// The closures can potentially block, so execution time should be the
|
/// The closures can potentially block, so execution time should be the
|
||||||
/// minimal possible such as save a variable.
|
/// minimal possible such as save a variable.
|
||||||
async fn create_sys_event_tasks<
|
fn create_sys_event_tasks<Fut1, Fut2, Fut3, Fut4, F1, F2, F3, F4>(
|
||||||
Fut1,
|
|
||||||
Fut2,
|
|
||||||
Fut3,
|
|
||||||
Fut4,
|
|
||||||
F1: Send + 'static,
|
|
||||||
F2: Send + 'static,
|
|
||||||
F3: Send + 'static,
|
|
||||||
F4: Send + 'static,
|
|
||||||
>(
|
|
||||||
&self,
|
&self,
|
||||||
mut on_prepare_for_sleep: F1,
|
mut on_prepare_for_sleep: F1,
|
||||||
mut on_prepare_for_shutdown: F2,
|
mut on_prepare_for_shutdown: F2,
|
||||||
mut on_lid_change: F3,
|
mut on_lid_change: F3,
|
||||||
mut on_external_power_change: F4,
|
mut on_external_power_change: F4,
|
||||||
) where
|
) -> impl Future<Output = ()> + Send
|
||||||
F1: FnMut(bool) -> Fut1,
|
where
|
||||||
F2: FnMut(bool) -> Fut2,
|
F1: FnMut(bool) -> Fut1 + Send + 'static,
|
||||||
F3: FnMut(bool) -> Fut3,
|
F2: FnMut(bool) -> Fut2 + Send + 'static,
|
||||||
F4: FnMut(bool) -> Fut4,
|
F3: FnMut(bool) -> Fut3 + Send + 'static,
|
||||||
|
F4: FnMut(bool) -> Fut4 + Send + 'static,
|
||||||
Fut1: Future<Output = ()> + Send,
|
Fut1: Future<Output = ()> + Send,
|
||||||
Fut2: Future<Output = ()> + Send,
|
Fut2: Future<Output = ()> + Send,
|
||||||
Fut3: Future<Output = ()> + Send,
|
Fut3: Future<Output = ()> + Send,
|
||||||
Fut4: Future<Output = ()> + Send,
|
Fut4: Future<Output = ()> + Send,
|
||||||
{
|
{
|
||||||
let connection = Connection::system()
|
async {
|
||||||
.await
|
let connection = Connection::system()
|
||||||
.expect("Controller could not create dbus connection");
|
.await
|
||||||
|
.expect("Controller could not create dbus connection");
|
||||||
|
|
||||||
let manager = ManagerProxy::builder(&connection)
|
let manager = ManagerProxy::builder(&connection)
|
||||||
.cache_properties(CacheProperties::No)
|
.cache_properties(CacheProperties::No)
|
||||||
.build()
|
.build()
|
||||||
.await
|
.await
|
||||||
.expect("Controller could not create ManagerProxy");
|
.expect("Controller could not create ManagerProxy");
|
||||||
|
|
||||||
let manager1 = manager.clone();
|
let manager1 = manager.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(mut notif) = manager1.receive_prepare_for_shutdown().await {
|
if let Ok(mut notif) = manager1.receive_prepare_for_shutdown().await {
|
||||||
while let Some(event) = notif.next().await {
|
while let Some(event) = notif.next().await {
|
||||||
// blocks thread :|
|
// blocks thread :|
|
||||||
if let Ok(args) = event.args() {
|
if let Ok(args) = event.args() {
|
||||||
debug!("Doing on_prepare_for_shutdown({})", args.start);
|
debug!("Doing on_prepare_for_shutdown({})", args.start);
|
||||||
on_prepare_for_shutdown(args.start).await;
|
on_prepare_for_shutdown(args.start).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let manager2 = manager.clone();
|
let manager2 = manager.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(mut notif) = manager2.receive_prepare_for_sleep().await {
|
if let Ok(mut notif) = manager2.receive_prepare_for_sleep().await {
|
||||||
while let Some(event) = notif.next().await {
|
while let Some(event) = notif.next().await {
|
||||||
// blocks thread :|
|
// blocks thread :|
|
||||||
if let Ok(args) = event.args() {
|
if let Ok(args) = event.args() {
|
||||||
debug!("Doing on_prepare_for_sleep({})", args.start);
|
debug!("Doing on_prepare_for_sleep({})", args.start);
|
||||||
on_prepare_for_sleep(args.start).await;
|
on_prepare_for_sleep(args.start).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let manager3 = manager.clone();
|
let manager3 = manager.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut last_power = manager3.on_external_power().await.unwrap_or_default();
|
let mut last_power = manager3.on_external_power().await.unwrap_or_default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(next) = manager3.on_external_power().await {
|
if let Ok(next) = manager3.on_external_power().await {
|
||||||
if next != last_power {
|
if next != last_power {
|
||||||
last_power = next;
|
last_power = next;
|
||||||
on_external_power_change(next).await;
|
on_external_power_change(next).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sleep(Duration::from_secs(2)).await;
|
||||||
}
|
}
|
||||||
sleep(Duration::from_secs(2)).await;
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut last_lid = manager.lid_closed().await.unwrap_or_default();
|
let mut last_lid = manager.lid_closed().await.unwrap_or_default();
|
||||||
// need to loop on these as they don't emit signals
|
// need to loop on these as they don't emit signals
|
||||||
loop {
|
loop {
|
||||||
if let Ok(next) = manager.lid_closed().await {
|
if let Ok(next) = manager.lid_closed().await {
|
||||||
if next != last_lid {
|
if next != last_lid {
|
||||||
last_lid = next;
|
last_lid = next;
|
||||||
on_lid_change(next).await;
|
on_lid_change(next).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sleep(Duration::from_secs(2)).await;
|
||||||
}
|
}
|
||||||
sleep(Duration::from_secs(2)).await;
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,3 +290,22 @@ pub trait GetSupported {
|
|||||||
|
|
||||||
fn get_supported() -> Self::A;
|
fn get_supported() -> Self::A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn start_tasks<T>(
|
||||||
|
mut zbus: T,
|
||||||
|
connection: &mut Connection,
|
||||||
|
signal_ctx: SignalContext<'static>,
|
||||||
|
) -> Result<(), RogError>
|
||||||
|
where
|
||||||
|
T: ZbusRun + Reloadable + CtrlTask + Clone,
|
||||||
|
{
|
||||||
|
let zbus_clone = zbus.clone();
|
||||||
|
|
||||||
|
zbus.reload()
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||||
|
zbus.add_to_server(connection).await;
|
||||||
|
|
||||||
|
zbus_clone.create_tasks(signal_ctx).await.ok();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<!--
|
|
||||||
Writes a data stream of length. Will force system thread to exit until
|
|
||||||
it is restarted
|
|
||||||
-->
|
|
||||||
<method name="Write">
|
|
||||||
<arg name="input" type="(ays)" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
The main loop is the base system set action if the user isn't running
|
|
||||||
the user daemon
|
|
||||||
-->
|
|
||||||
<method name="RunMainLoop">
|
|
||||||
<arg name="start" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Get the device state as stored by asusd
|
|
||||||
-->
|
|
||||||
<method name="DeviceState">
|
|
||||||
<arg type="(bub(ssss)bbbu)" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set base brightness level
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
Set base brightness level
|
|
||||||
-->
|
|
||||||
<property name="Brightness" type="u" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set which builtin animation is used for each stage
|
|
||||||
-->
|
|
||||||
<property name="BuiltinAnimations" type="(ssss)" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Enable the builtin animations or not. This is quivalent to "Powersave
|
|
||||||
animations" in Armory crate
|
|
||||||
-->
|
|
||||||
<property name="BuiltinsEnabled" type="b" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set whether the AniMe is enabled at all
|
|
||||||
-->
|
|
||||||
<property name="EnableDisplay" type="b" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set if to turn the AniMe Matrix off when the lid is closed
|
|
||||||
-->
|
|
||||||
<property name="OffWhenLidClosed" type="b" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set if to turn the AniMe Matrix off when the laptop is suspended
|
|
||||||
-->
|
|
||||||
<property name="OffWhenSuspended" type="b" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set if to turn the AniMe Matrix off when external power is unplugged
|
|
||||||
-->
|
|
||||||
<property name="OffWhenUnplugged" type="b" access="readwrite"/>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<!--
|
|
||||||
Get the data set for every mode available
|
|
||||||
-->
|
|
||||||
<method name="AllModeData">
|
|
||||||
<arg type="a{u(us(yyy)(yyy)ss)}" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
On machine that have some form of either per-key keyboard or per-zone
|
|
||||||
this can be used to write custom effects over dbus. The input is a
|
|
||||||
nested `Vec<Vec<8>>` where `Vec<u8>` is a raw USB packet
|
|
||||||
-->
|
|
||||||
<method name="DirectAddressingRaw">
|
|
||||||
<arg name="data" type="aay" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Return the current LED brightness
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
Set the keyboard brightness level (0-3)
|
|
||||||
-->
|
|
||||||
<property name="Brightness" type="u" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Return the device type for this Aura keyboard
|
|
||||||
-->
|
|
||||||
<property name="DeviceType" type="s" access="read"/>
|
|
||||||
<!--
|
|
||||||
The current mode data
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
Set an Aura effect if the effect mode or zone is supported.
|
|
||||||
|
|
||||||
On success the aura config file is read to refresh cached values, then
|
|
||||||
the effect is stored and config written to disk.
|
|
||||||
-->
|
|
||||||
<property name="LedMode" type="u" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
The current mode data
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
Set an Aura effect if the effect mode or zone is supported.
|
|
||||||
|
|
||||||
On success the aura config file is read to refresh cached values, then
|
|
||||||
the effect is stored and config written to disk.
|
|
||||||
-->
|
|
||||||
<property name="LedModeData" type="(us(yyy)(yyy)ss)" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Set a variety of states, input is array of enum.
|
|
||||||
`enabled` sets if the sent array should be disabled or enabled
|
|
||||||
|
|
||||||
For Modern ROG devices the "enabled" flag is ignored.
|
|
||||||
-->
|
|
||||||
<property name="LedPower" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Total levels of brightness available
|
|
||||||
-->
|
|
||||||
<property name="SupportedBrightness" type="au" access="read"/>
|
|
||||||
<!--
|
|
||||||
The total available modes
|
|
||||||
-->
|
|
||||||
<property name="SupportedModes" type="au" access="read"/>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<!--
|
|
||||||
Set all fan curves for a profile to enabled status. Will also activate a
|
|
||||||
fan curve if in the same profile mode
|
|
||||||
-->
|
|
||||||
<method name="SetFanCurvesEnabled">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set a single fan curve for a profile to enabled status. Will also
|
|
||||||
activate a fan curve if in the same profile mode
|
|
||||||
-->
|
|
||||||
<method name="SetProfileFanCurveEnabled">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
<arg name="fan" type="s" direction="in"/>
|
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Get the fan-curve data for the currently active PlatformPolicy
|
|
||||||
-->
|
|
||||||
<method name="FanCurveData">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
<arg type="a(s(yyyyyyyy)(yyyyyyyy)b)" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set the fan curve for the specified profile.
|
|
||||||
Will also activate the fan curve if the user is in the same mode.
|
|
||||||
-->
|
|
||||||
<method name="SetFanCurve">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
<arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy)b)" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Reset the stored (self) and device curve to the defaults of the
|
|
||||||
platform.
|
|
||||||
|
|
||||||
Each platform_profile has a different default and the defualt can be
|
|
||||||
read only for the currently active profile.
|
|
||||||
-->
|
|
||||||
<method name="SetActiveCurveToDefaults">
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Reset the stored (self) and device curve to the defaults of the
|
|
||||||
platform.
|
|
||||||
|
|
||||||
Each platform_profile has a different default and the defualt can be
|
|
||||||
read only for the currently active profile.
|
|
||||||
-->
|
|
||||||
<method name="ResetProfileCurves">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
</method>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<!--
|
|
||||||
Returns a list of property names that this system supports
|
|
||||||
-->
|
|
||||||
<method name="SupportedProperties">
|
|
||||||
<arg type="as" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<method name="SupportedInterfaces">
|
|
||||||
<arg type="as" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Toggle to next platform_profile. Names provided by `Profiles`.
|
|
||||||
If fan-curves are supported will also activate a fan curve for profile.
|
|
||||||
-->
|
|
||||||
<method name="NextThrottleThermalPolicy">
|
|
||||||
</method>
|
|
||||||
<property name="ChargeControlEndThreshold" type="y" access="readwrite"/>
|
|
||||||
<property name="DgpuDisable" type="b" access="read"/>
|
|
||||||
<property name="EgpuEnable" type="b" access="read"/>
|
|
||||||
<property name="GpuMuxMode" type="y" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Get the `panel_od` value from platform. Updates the stored value in
|
|
||||||
internal config also.
|
|
||||||
-->
|
|
||||||
<property name="MiniLedMode" type="b" access="readwrite"/>
|
|
||||||
<property name="NvDynamicBoost" type="y" access="readwrite"/>
|
|
||||||
<property name="NvTempTarget" type="y" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
Get the `panel_od` value from platform. Updates the stored value in
|
|
||||||
internal config also.
|
|
||||||
-->
|
|
||||||
<property name="PanelOd" type="b" access="readwrite"/>
|
|
||||||
<property name="PostAnimationSound" type="b" access="readwrite"/>
|
|
||||||
<property name="PptApuSppt" type="y" access="readwrite"/>
|
|
||||||
<property name="PptFppt" type="y" access="readwrite"/>
|
|
||||||
<!--
|
|
||||||
************************************************************************
|
|
||||||
-->
|
|
||||||
<property name="PptPl1Spl" type="y" access="readwrite"/>
|
|
||||||
<property name="PptPl2Sppt" type="y" access="readwrite"/>
|
|
||||||
<property name="PptPlatformSppt" type="y" access="readwrite"/>
|
|
||||||
<property name="ThrottleThermalPolicy" type="s" access="readwrite"/>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
Generated by typeshare 1.7.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
export enum AnimBooting {
|
|
||||||
GlitchConstruction = "GlitchConstruction",
|
|
||||||
StaticEmergence = "StaticEmergence",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AnimAwake {
|
|
||||||
BinaryBannerScroll = "BinaryBannerScroll",
|
|
||||||
RogLogoGlitch = "RogLogoGlitch",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AnimSleeping {
|
|
||||||
BannerSwipe = "BannerSwipe",
|
|
||||||
Starfield = "Starfield",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AnimShutdown {
|
|
||||||
GlitchOut = "GlitchOut",
|
|
||||||
SeeYa = "SeeYa",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Animations {
|
|
||||||
boot: AnimBooting;
|
|
||||||
awake: AnimAwake;
|
|
||||||
sleep: AnimSleeping;
|
|
||||||
shutdown: AnimShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Base LED brightness of the display */
|
|
||||||
export enum Brightness {
|
|
||||||
Off = "Off",
|
|
||||||
Low = "Low",
|
|
||||||
Med = "Med",
|
|
||||||
High = "High",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeviceState {
|
|
||||||
display_enabled: boolean;
|
|
||||||
display_brightness: Brightness;
|
|
||||||
builtin_anims_enabled: boolean;
|
|
||||||
builtin_anims: Animations;
|
|
||||||
off_when_unplugged: boolean;
|
|
||||||
off_when_suspended: boolean;
|
|
||||||
off_when_lid_closed: boolean;
|
|
||||||
brightness_on_battery: Brightness;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AnimeType {
|
|
||||||
GA401 = "GA401",
|
|
||||||
GA402 = "GA402",
|
|
||||||
GU604 = "GU604",
|
|
||||||
Unknown = "Unknown",
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
Generated by typeshare 1.7.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Represents the per-key raw USB packets */
|
|
||||||
export type UsbPackets = number[][];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A `UsbPackets` contains all data to change the full set of keyboard
|
|
||||||
* key colours individually.
|
|
||||||
*
|
|
||||||
* Each row of the internal array is a full HID packet that can be sent
|
|
||||||
* to the keyboard EC. One row controls one group of keys, these keys are not
|
|
||||||
* necessarily all on the same row of the keyboard, with some splitting between
|
|
||||||
* two rows.
|
|
||||||
*/
|
|
||||||
export interface LedUsbPackets {
|
|
||||||
/** The packet data used to send data to the USB keyboard */
|
|
||||||
usb_packets: UsbPackets;
|
|
||||||
/**
|
|
||||||
* 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: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Colour {
|
|
||||||
r: number;
|
|
||||||
g: number;
|
|
||||||
b: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Enum of modes that convert to the actual number required by a USB HID packet */
|
|
||||||
export enum AuraModeNum {
|
|
||||||
Static = "Static",
|
|
||||||
Breathe = "Breathe",
|
|
||||||
Strobe = "Strobe",
|
|
||||||
Rainbow = "Rainbow",
|
|
||||||
Star = "Star",
|
|
||||||
Rain = "Rain",
|
|
||||||
Highlight = "Highlight",
|
|
||||||
Laser = "Laser",
|
|
||||||
Ripple = "Ripple",
|
|
||||||
Pulse = "Pulse",
|
|
||||||
Comet = "Comet",
|
|
||||||
Flash = "Flash",
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Base effects have no zoning, while multizone is 1-4 */
|
|
||||||
export enum AuraZone {
|
|
||||||
/** Used if keyboard has no zones, or if setting all */
|
|
||||||
None = "None",
|
|
||||||
/** Leftmost zone */
|
|
||||||
Key1 = "Key1",
|
|
||||||
/** Zone after leftmost */
|
|
||||||
Key2 = "Key2",
|
|
||||||
/** Zone second from right */
|
|
||||||
Key3 = "Key3",
|
|
||||||
/** Rightmost zone */
|
|
||||||
Key4 = "Key4",
|
|
||||||
/** Logo on the lid (or elsewhere?) */
|
|
||||||
Logo = "Logo",
|
|
||||||
/** The left part of a lightbar (typically on the front of laptop) */
|
|
||||||
BarLeft = "BarLeft",
|
|
||||||
/** The right part of a lightbar */
|
|
||||||
BarRight = "BarRight",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Speed {
|
|
||||||
Low = "Low",
|
|
||||||
Med = "Med",
|
|
||||||
High = "High",
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for Rainbow mode.
|
|
||||||
*
|
|
||||||
* Enum corresponds to the required integer value
|
|
||||||
*/
|
|
||||||
export enum Direction {
|
|
||||||
Right = "Right",
|
|
||||||
Left = "Left",
|
|
||||||
Up = "Up",
|
|
||||||
Down = "Down",
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default factory modes structure. This easily converts to an USB HID packet
|
|
||||||
* with:
|
|
||||||
* ```rust
|
|
||||||
* // let bytes: [u8; LED_MSG_LEN] = mode.into();
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export interface AuraEffect {
|
|
||||||
/** The effect type */
|
|
||||||
mode: AuraModeNum;
|
|
||||||
/** `AuraZone::None` for no zone or zoneless keyboards */
|
|
||||||
zone: AuraZone;
|
|
||||||
/** Primary colour for all modes */
|
|
||||||
colour1: Colour;
|
|
||||||
/** Secondary colour in some modes like Breathing or Stars */
|
|
||||||
colour2: Colour;
|
|
||||||
/** One of three speeds for modes that support speed (most that animate) */
|
|
||||||
speed: Speed;
|
|
||||||
/** Up, down, left, right. Only Rainbow mode seems to use this */
|
|
||||||
direction: Direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The powerr zones this laptop supports */
|
|
||||||
export enum PowerZones {
|
|
||||||
/** The logo on some laptop lids */
|
|
||||||
Logo = "Logo",
|
|
||||||
/** The full keyboard (not zones) */
|
|
||||||
Keyboard = "Keyboard",
|
|
||||||
/** The lightbar, typically on the front of the laptop */
|
|
||||||
Lightbar = "Lightbar",
|
|
||||||
/** The leds that may be placed around the edge of the laptop lid */
|
|
||||||
Lid = "Lid",
|
|
||||||
/** The led strip on the rear of some laptops */
|
|
||||||
RearGlow = "RearGlow",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface KbAuraPowerState {
|
|
||||||
zone: PowerZones;
|
|
||||||
boot: boolean;
|
|
||||||
awake: boolean;
|
|
||||||
sleep: boolean;
|
|
||||||
shutdown: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Track and control the Aura keyboard power state
|
|
||||||
*
|
|
||||||
* # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
|
||||||
*
|
|
||||||
* | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
|
||||||
* |--------|---------|---------|---------|----------|
|
|
||||||
* |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
|
||||||
* |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
|
||||||
* |00000100| 00000000| 00000000| 00000000|awake_logo|
|
|
||||||
* |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
|
||||||
* |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
|
||||||
* |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
|
||||||
* |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
|
||||||
* |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
|
||||||
* |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
|
||||||
* |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
|
||||||
* |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
|
||||||
* |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
|
||||||
* |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
|
||||||
* |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
|
||||||
* |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
|
||||||
* |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
|
||||||
* |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
|
||||||
* |00000000| 00000000| 00000000| 00000010|awake_rear|
|
|
||||||
* |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
|
||||||
* |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
|
||||||
*/
|
|
||||||
export interface AuraPower {
|
|
||||||
keyboard: KbAuraPowerState;
|
|
||||||
logo: KbAuraPowerState;
|
|
||||||
lightbar: KbAuraPowerState;
|
|
||||||
lid: KbAuraPowerState;
|
|
||||||
rear_glow: KbAuraPowerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AuraDevTuf {
|
|
||||||
Boot = "Boot",
|
|
||||||
Awake = "Awake",
|
|
||||||
Sleep = "Sleep",
|
|
||||||
Keyboard = "Keyboard",
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* # Bits for older 0x1866 keyboard model
|
|
||||||
*
|
|
||||||
* Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
|
||||||
* Keybord and Lightbar regardless of if either are enabled (or Awake is
|
|
||||||
* enabled)
|
|
||||||
*
|
|
||||||
* | Byte 1 | Byte 2 | Byte 3 | function | hex |
|
|
||||||
* |------------|------------|------------|----------|----------|
|
|
||||||
* | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
|
|
||||||
* | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
|
|
||||||
* | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
|
|
||||||
* | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
|
|
||||||
* | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
|
|
||||||
* | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
|
|
||||||
*/
|
|
||||||
export enum AuraDevRog1 {
|
|
||||||
Awake = "Awake",
|
|
||||||
Keyboard = "Keyboard",
|
|
||||||
Lightbar = "Lightbar",
|
|
||||||
Boot = "Boot",
|
|
||||||
Sleep = "Sleep",
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This struct is intended as a helper to pass args to generic dbus interface */
|
|
||||||
export interface AuraPowerDev {
|
|
||||||
/**
|
|
||||||
* TUF laptops use a similar style of control to the older ROG devices but
|
|
||||||
* through WMI
|
|
||||||
*/
|
|
||||||
tuf: AuraDevTuf[];
|
|
||||||
/**
|
|
||||||
* Pre-0x19b6 devices use a different smaller scheme to the newer ROG
|
|
||||||
* devices
|
|
||||||
*/
|
|
||||||
old_rog: AuraDevRog1[];
|
|
||||||
/** ASUS standardised control scheme from 2020 onwards */
|
|
||||||
rog: AuraPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LedBrightness {
|
|
||||||
Off = "Off",
|
|
||||||
Low = "Low",
|
|
||||||
Med = "Med",
|
|
||||||
High = "High",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AuraDevice {
|
|
||||||
Tuf = "Tuf",
|
|
||||||
X1854 = "X1854",
|
|
||||||
X1869 = "X1869",
|
|
||||||
X1866 = "X1866",
|
|
||||||
X18c6 = "X18c6",
|
|
||||||
X19b6 = "X19b6",
|
|
||||||
X1a30 = "X1a30",
|
|
||||||
X1abe = "X1abe",
|
|
||||||
Unknown = "Unknown",
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Generated by typeshare 1.7.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
export enum GpuMode {
|
|
||||||
Discrete = "Discrete",
|
|
||||||
Optimus = "Optimus",
|
|
||||||
Integrated = "Integrated",
|
|
||||||
Egpu = "Egpu",
|
|
||||||
Vfio = "Vfio",
|
|
||||||
Ultimate = "Ultimate",
|
|
||||||
Error = "Error",
|
|
||||||
NotSupported = "NotSupported",
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum PlatformPolicy {
|
|
||||||
Balanced = "Balanced",
|
|
||||||
Performance = "Performance",
|
|
||||||
Quiet = "Quiet",
|
|
||||||
}
|
|
||||||
|
|
||||||
/** CamelCase names of the properties. Intended for use with DBUS */
|
|
||||||
export enum Properties {
|
|
||||||
ChargeControlEndThreshold = "ChargeControlEndThreshold",
|
|
||||||
DgpuDisable = "DgpuDisable",
|
|
||||||
GpuMuxMode = "GpuMuxMode",
|
|
||||||
PostAnimationSound = "PostAnimationSound",
|
|
||||||
PanelOd = "PanelOd",
|
|
||||||
MiniLedMode = "MiniLedMode",
|
|
||||||
EgpuEnable = "EgpuEnable",
|
|
||||||
PlatformPolicy = "PlatformPolicy",
|
|
||||||
PptPl1Spl = "PptPl1Spl",
|
|
||||||
PptPl2Sppt = "PptPl2Sppt",
|
|
||||||
PptFppt = "PptFppt",
|
|
||||||
PptApuSppt = "PptApuSppt",
|
|
||||||
PptPlatformSppt = "PptPlatformSppt",
|
|
||||||
NvDynamicBoost = "NvDynamicBoost",
|
|
||||||
NvTempTarget = "NvTempTarget",
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
Generated by typeshare 1.7.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
export enum FanCurvePU {
|
|
||||||
CPU = "CPU",
|
|
||||||
GPU = "GPU",
|
|
||||||
MID = "MID",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CurveData {
|
|
||||||
fan: FanCurvePU;
|
|
||||||
pwm: [number, number, number, number, number, number, number, number];
|
|
||||||
temp: [number, number, number, number, number, number, number, number];
|
|
||||||
enabled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main purpose of `FanCurves` is to enable restoring state on system boot */
|
|
||||||
export interface FanCurveProfiles {
|
|
||||||
balanced: CurveData[];
|
|
||||||
performance: CurveData[];
|
|
||||||
quiet: CurveData[];
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@ where
|
|||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
|
.truncate(false)
|
||||||
.open(self.file_path())
|
.open(self.file_path())
|
||||||
.unwrap_or_else(|e| panic!("Could not open {:?} {e}", self.file_path()))
|
.unwrap_or_else(|e| panic!("Could not open {:?} {e}", self.file_path()))
|
||||||
}
|
}
|
||||||
@@ -109,6 +110,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Open and parse the config file to self from ron format
|
||||||
|
fn read_new(&self) -> Option<Self> {
|
||||||
|
if let Ok(data) = fs::read_to_string(self.file_path()) {
|
||||||
|
if data.is_empty() {
|
||||||
|
warn!("File is empty {:?}", self.file_path());
|
||||||
|
} else if let Ok(data) = ron::from_str(&data) {
|
||||||
|
return Some(data);
|
||||||
|
} else {
|
||||||
|
warn!("Could not deserialise {:?}", self.file_path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Write the config file data to pretty ron format
|
/// Write the config file data to pretty ron format
|
||||||
fn write(&self) {
|
fn write(&self) {
|
||||||
let mut file = match File::create(self.file_path()) {
|
let mut file = match File::create(self.file_path()) {
|
||||||
|
|||||||
+3
-2
@@ -7,11 +7,12 @@ After=nvidia-powerd.service systemd-udevd.service
|
|||||||
[Service]
|
[Service]
|
||||||
Environment=IS_SERVICE=1
|
Environment=IS_SERVICE=1
|
||||||
Environment=RUST_LOG="info"
|
Environment=RUST_LOG="info"
|
||||||
# ExecStartPre=/bin/sleep 2 # was required only for slow devices
|
# required to prevent init issues with hid_asus and MCU
|
||||||
|
ExecStartPre=/bin/sleep 1
|
||||||
ExecStart=/usr/bin/asusd
|
ExecStart=/usr/bin/asusd
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=1
|
RestartSec=1
|
||||||
Type=dbus
|
Type=dbus
|
||||||
BusName=org.asuslinux.Daemon
|
BusName=org.asuslinux.Daemon
|
||||||
SELinuxContext=system_u:system_r:unconfined_t:s0
|
SELinuxContext=system_u:system_r:unconfined_t:s0
|
||||||
#SELinuxContext=system_u:object_r:modules_object_t:s0
|
#SELinuxContext=system_u:object_r:modules_object_t:s0
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
/* eslint-env node */
|
|
||||||
module.exports = {
|
|
||||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
||||||
parser: "@typescript-eslint/parser",
|
|
||||||
plugins: ["@typescript-eslint"],
|
|
||||||
root: true,
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
// enable additional rules
|
|
||||||
indent: ["error", 4],
|
|
||||||
"linebreak-style": ["error", "unix"],
|
|
||||||
quotes: ["error", "double"],
|
|
||||||
semi: ["error", "always"],
|
|
||||||
|
|
||||||
// override configuration set by extending "eslint:recommended"
|
|
||||||
"no-empty": "warn",
|
|
||||||
"no-cond-assign": ["error", "always"],
|
|
||||||
|
|
||||||
// disable rules from base configurations
|
|
||||||
"for-direction": "off",
|
|
||||||
|
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Generated files
|
|
||||||
/@types/gir-generated/*
|
|
||||||
|
|
||||||
# Build outputes
|
|
||||||
/dist/
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# Node configuration and modules
|
|
||||||
/package.json
|
|
||||||
/node_modules/
|
|
||||||
|
|
||||||
# Files I prefer not to be formatted
|
|
||||||
*.md
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 100,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": false,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"arrowParens": "always"
|
|
||||||
}
|
|
||||||
@@ -1,373 +0,0 @@
|
|||||||
Mozilla Public License Version 2.0
|
|
||||||
==================================
|
|
||||||
|
|
||||||
1. Definitions
|
|
||||||
--------------
|
|
||||||
|
|
||||||
1.1. "Contributor"
|
|
||||||
means each individual or legal entity that creates, contributes to
|
|
||||||
the creation of, or owns Covered Software.
|
|
||||||
|
|
||||||
1.2. "Contributor Version"
|
|
||||||
means the combination of the Contributions of others (if any) used
|
|
||||||
by a Contributor and that particular Contributor's Contribution.
|
|
||||||
|
|
||||||
1.3. "Contribution"
|
|
||||||
means Covered Software of a particular Contributor.
|
|
||||||
|
|
||||||
1.4. "Covered Software"
|
|
||||||
means Source Code Form to which the initial Contributor has attached
|
|
||||||
the notice in Exhibit A, the Executable Form of such Source Code
|
|
||||||
Form, and Modifications of such Source Code Form, in each case
|
|
||||||
including portions thereof.
|
|
||||||
|
|
||||||
1.5. "Incompatible With Secondary Licenses"
|
|
||||||
means
|
|
||||||
|
|
||||||
(a) that the initial Contributor has attached the notice described
|
|
||||||
in Exhibit B to the Covered Software; or
|
|
||||||
|
|
||||||
(b) that the Covered Software was made available under the terms of
|
|
||||||
version 1.1 or earlier of the License, but not also under the
|
|
||||||
terms of a Secondary License.
|
|
||||||
|
|
||||||
1.6. "Executable Form"
|
|
||||||
means any form of the work other than Source Code Form.
|
|
||||||
|
|
||||||
1.7. "Larger Work"
|
|
||||||
means a work that combines Covered Software with other material, in
|
|
||||||
a separate file or files, that is not Covered Software.
|
|
||||||
|
|
||||||
1.8. "License"
|
|
||||||
means this document.
|
|
||||||
|
|
||||||
1.9. "Licensable"
|
|
||||||
means having the right to grant, to the maximum extent possible,
|
|
||||||
whether at the time of the initial grant or subsequently, any and
|
|
||||||
all of the rights conveyed by this License.
|
|
||||||
|
|
||||||
1.10. "Modifications"
|
|
||||||
means any of the following:
|
|
||||||
|
|
||||||
(a) any file in Source Code Form that results from an addition to,
|
|
||||||
deletion from, or modification of the contents of Covered
|
|
||||||
Software; or
|
|
||||||
|
|
||||||
(b) any new file in Source Code Form that contains any Covered
|
|
||||||
Software.
|
|
||||||
|
|
||||||
1.11. "Patent Claims" of a Contributor
|
|
||||||
means any patent claim(s), including without limitation, method,
|
|
||||||
process, and apparatus claims, in any patent Licensable by such
|
|
||||||
Contributor that would be infringed, but for the grant of the
|
|
||||||
License, by the making, using, selling, offering for sale, having
|
|
||||||
made, import, or transfer of either its Contributions or its
|
|
||||||
Contributor Version.
|
|
||||||
|
|
||||||
1.12. "Secondary License"
|
|
||||||
means either the GNU General Public License, Version 2.0, the GNU
|
|
||||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
|
||||||
Public License, Version 3.0, or any later versions of those
|
|
||||||
licenses.
|
|
||||||
|
|
||||||
1.13. "Source Code Form"
|
|
||||||
means the form of the work preferred for making modifications.
|
|
||||||
|
|
||||||
1.14. "You" (or "Your")
|
|
||||||
means an individual or a legal entity exercising rights under this
|
|
||||||
License. For legal entities, "You" includes any entity that
|
|
||||||
controls, is controlled by, or is under common control with You. For
|
|
||||||
purposes of this definition, "control" means (a) the power, direct
|
|
||||||
or indirect, to cause the direction or management of such entity,
|
|
||||||
whether by contract or otherwise, or (b) ownership of more than
|
|
||||||
fifty percent (50%) of the outstanding shares or beneficial
|
|
||||||
ownership of such entity.
|
|
||||||
|
|
||||||
2. License Grants and Conditions
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
2.1. Grants
|
|
||||||
|
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license:
|
|
||||||
|
|
||||||
(a) under intellectual property rights (other than patent or trademark)
|
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
|
||||||
Contributions, either on an unmodified basis, with Modifications, or
|
|
||||||
as part of a Larger Work; and
|
|
||||||
|
|
||||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
|
||||||
for sale, have made, import, and otherwise transfer either its
|
|
||||||
Contributions or its Contributor Version.
|
|
||||||
|
|
||||||
2.2. Effective Date
|
|
||||||
|
|
||||||
The licenses granted in Section 2.1 with respect to any Contribution
|
|
||||||
become effective for each Contribution on the date the Contributor first
|
|
||||||
distributes such Contribution.
|
|
||||||
|
|
||||||
2.3. Limitations on Grant Scope
|
|
||||||
|
|
||||||
The licenses granted in this Section 2 are the only rights granted under
|
|
||||||
this License. No additional rights or licenses will be implied from the
|
|
||||||
distribution or licensing of Covered Software under this License.
|
|
||||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
|
||||||
Contributor:
|
|
||||||
|
|
||||||
(a) for any code that a Contributor has removed from Covered Software;
|
|
||||||
or
|
|
||||||
|
|
||||||
(b) for infringements caused by: (i) Your and any other third party's
|
|
||||||
modifications of Covered Software, or (ii) the combination of its
|
|
||||||
Contributions with other software (except as part of its Contributor
|
|
||||||
Version); or
|
|
||||||
|
|
||||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
|
||||||
its Contributions.
|
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks,
|
|
||||||
or logos of any Contributor (except as may be necessary to comply with
|
|
||||||
the notice requirements in Section 3.4).
|
|
||||||
|
|
||||||
2.4. Subsequent Licenses
|
|
||||||
|
|
||||||
No Contributor makes additional grants as a result of Your choice to
|
|
||||||
distribute the Covered Software under a subsequent version of this
|
|
||||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
|
||||||
permitted under the terms of Section 3.3).
|
|
||||||
|
|
||||||
2.5. Representation
|
|
||||||
|
|
||||||
Each Contributor represents that the Contributor believes its
|
|
||||||
Contributions are its original creation(s) or it has sufficient rights
|
|
||||||
to grant the rights to its Contributions conveyed by this License.
|
|
||||||
|
|
||||||
2.6. Fair Use
|
|
||||||
|
|
||||||
This License is not intended to limit any rights You have under
|
|
||||||
applicable copyright doctrines of fair use, fair dealing, or other
|
|
||||||
equivalents.
|
|
||||||
|
|
||||||
2.7. Conditions
|
|
||||||
|
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
|
||||||
in Section 2.1.
|
|
||||||
|
|
||||||
3. Responsibilities
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
3.1. Distribution of Source Form
|
|
||||||
|
|
||||||
All distribution of Covered Software in Source Code Form, including any
|
|
||||||
Modifications that You create or to which You contribute, must be under
|
|
||||||
the terms of this License. You must inform recipients that the Source
|
|
||||||
Code Form of the Covered Software is governed by the terms of this
|
|
||||||
License, and how they can obtain a copy of this License. You may not
|
|
||||||
attempt to alter or restrict the recipients' rights in the Source Code
|
|
||||||
Form.
|
|
||||||
|
|
||||||
3.2. Distribution of Executable Form
|
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
|
||||||
|
|
||||||
(a) such Covered Software must also be made available in Source Code
|
|
||||||
Form, as described in Section 3.1, and You must inform recipients of
|
|
||||||
the Executable Form how they can obtain a copy of such Source Code
|
|
||||||
Form by reasonable means in a timely manner, at a charge no more
|
|
||||||
than the cost of distribution to the recipient; and
|
|
||||||
|
|
||||||
(b) You may distribute such Executable Form under the terms of this
|
|
||||||
License, or sublicense it under different terms, provided that the
|
|
||||||
license for the Executable Form does not attempt to limit or alter
|
|
||||||
the recipients' rights in the Source Code Form under this License.
|
|
||||||
|
|
||||||
3.3. Distribution of a Larger Work
|
|
||||||
|
|
||||||
You may create and distribute a Larger Work under terms of Your choice,
|
|
||||||
provided that You also comply with the requirements of this License for
|
|
||||||
the Covered Software. If the Larger Work is a combination of Covered
|
|
||||||
Software with a work governed by one or more Secondary Licenses, and the
|
|
||||||
Covered Software is not Incompatible With Secondary Licenses, this
|
|
||||||
License permits You to additionally distribute such Covered Software
|
|
||||||
under the terms of such Secondary License(s), so that the recipient of
|
|
||||||
the Larger Work may, at their option, further distribute the Covered
|
|
||||||
Software under the terms of either this License or such Secondary
|
|
||||||
License(s).
|
|
||||||
|
|
||||||
3.4. Notices
|
|
||||||
|
|
||||||
You may not remove or alter the substance of any license notices
|
|
||||||
(including copyright notices, patent notices, disclaimers of warranty,
|
|
||||||
or limitations of liability) contained within the Source Code Form of
|
|
||||||
the Covered Software, except that You may alter any license notices to
|
|
||||||
the extent required to remedy known factual inaccuracies.
|
|
||||||
|
|
||||||
3.5. Application of Additional Terms
|
|
||||||
|
|
||||||
You may choose to offer, and to charge a fee for, warranty, support,
|
|
||||||
indemnity or liability obligations to one or more recipients of Covered
|
|
||||||
Software. However, You may do so only on Your own behalf, and not on
|
|
||||||
behalf of any Contributor. You must make it absolutely clear that any
|
|
||||||
such warranty, support, indemnity, or liability obligation is offered by
|
|
||||||
You alone, and You hereby agree to indemnify every Contributor for any
|
|
||||||
liability incurred by such Contributor as a result of warranty, support,
|
|
||||||
indemnity or liability terms You offer. You may include additional
|
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
|
||||||
jurisdiction.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this
|
|
||||||
License with respect to some or all of the Covered Software due to
|
|
||||||
statute, judicial order, or regulation then You must: (a) comply with
|
|
||||||
the terms of this License to the maximum extent possible; and (b)
|
|
||||||
describe the limitations and the code they affect. Such description must
|
|
||||||
be placed in a text file included with all distributions of the Covered
|
|
||||||
Software under this License. Except to the extent prohibited by statute
|
|
||||||
or regulation, such description must be sufficiently detailed for a
|
|
||||||
recipient of ordinary skill to be able to understand it.
|
|
||||||
|
|
||||||
5. Termination
|
|
||||||
--------------
|
|
||||||
|
|
||||||
5.1. The rights granted under this License will terminate automatically
|
|
||||||
if You fail to comply with any of its terms. However, if You become
|
|
||||||
compliant, then the rights granted under this License from a particular
|
|
||||||
Contributor are reinstated (a) provisionally, unless and until such
|
|
||||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
|
||||||
ongoing basis, if such Contributor fails to notify You of the
|
|
||||||
non-compliance by some reasonable means prior to 60 days after You have
|
|
||||||
come back into compliance. Moreover, Your grants from a particular
|
|
||||||
Contributor are reinstated on an ongoing basis if such Contributor
|
|
||||||
notifies You of the non-compliance by some reasonable means, this is the
|
|
||||||
first time You have received notice of non-compliance with this License
|
|
||||||
from such Contributor, and You become compliant prior to 30 days after
|
|
||||||
Your receipt of the notice.
|
|
||||||
|
|
||||||
5.2. If You initiate litigation against any entity by asserting a patent
|
|
||||||
infringement claim (excluding declaratory judgment actions,
|
|
||||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
|
||||||
directly or indirectly infringes any patent, then the rights granted to
|
|
||||||
You by any and all Contributors for the Covered Software under Section
|
|
||||||
2.1 of this License shall terminate.
|
|
||||||
|
|
||||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
|
||||||
end user license agreements (excluding distributors and resellers) which
|
|
||||||
have been validly granted by You or Your distributors under this License
|
|
||||||
prior to termination shall survive termination.
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 6. Disclaimer of Warranty *
|
|
||||||
* ------------------------- *
|
|
||||||
* *
|
|
||||||
* Covered Software is provided under this License on an "as is" *
|
|
||||||
* basis, without warranty of any kind, either expressed, implied, or *
|
|
||||||
* statutory, including, without limitation, warranties that the *
|
|
||||||
* Covered Software is free of defects, merchantable, fit for a *
|
|
||||||
* particular purpose or non-infringing. The entire risk as to the *
|
|
||||||
* quality and performance of the Covered Software is with You. *
|
|
||||||
* Should any Covered Software prove defective in any respect, You *
|
|
||||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
|
||||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
|
||||||
* essential part of this License. No use of any Covered Software is *
|
|
||||||
* authorized under this License except under this disclaimer. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 7. Limitation of Liability *
|
|
||||||
* -------------------------- *
|
|
||||||
* *
|
|
||||||
* Under no circumstances and under no legal theory, whether tort *
|
|
||||||
* (including negligence), contract, or otherwise, shall any *
|
|
||||||
* Contributor, or anyone who distributes Covered Software as *
|
|
||||||
* permitted above, be liable to You for any direct, indirect, *
|
|
||||||
* special, incidental, or consequential damages of any character *
|
|
||||||
* including, without limitation, damages for lost profits, loss of *
|
|
||||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
|
||||||
* and all other commercial damages or losses, even if such party *
|
|
||||||
* shall have been informed of the possibility of such damages. This *
|
|
||||||
* limitation of liability shall not apply to liability for death or *
|
|
||||||
* personal injury resulting from such party's negligence to the *
|
|
||||||
* extent applicable law prohibits such limitation. Some *
|
|
||||||
* jurisdictions do not allow the exclusion or limitation of *
|
|
||||||
* incidental or consequential damages, so this exclusion and *
|
|
||||||
* limitation may not apply to You. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
8. Litigation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the
|
|
||||||
courts of a jurisdiction where the defendant maintains its principal
|
|
||||||
place of business and such litigation shall be governed by laws of that
|
|
||||||
jurisdiction, without reference to its conflict-of-law provisions.
|
|
||||||
Nothing in this Section shall prevent a party's ability to bring
|
|
||||||
cross-claims or counter-claims.
|
|
||||||
|
|
||||||
9. Miscellaneous
|
|
||||||
----------------
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject
|
|
||||||
matter hereof. If any provision of this License is held to be
|
|
||||||
unenforceable, such provision shall be reformed only to the extent
|
|
||||||
necessary to make it enforceable. Any law or regulation which provides
|
|
||||||
that the language of a contract shall be construed against the drafter
|
|
||||||
shall not be used to construe this License against a Contributor.
|
|
||||||
|
|
||||||
10. Versions of the License
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
10.1. New Versions
|
|
||||||
|
|
||||||
Mozilla Foundation is the license steward. Except as provided in Section
|
|
||||||
10.3, no one other than the license steward has the right to modify or
|
|
||||||
publish new versions of this License. Each version will be given a
|
|
||||||
distinguishing version number.
|
|
||||||
|
|
||||||
10.2. Effect of New Versions
|
|
||||||
|
|
||||||
You may distribute the Covered Software under the terms of the version
|
|
||||||
of the License under which You originally received the Covered Software,
|
|
||||||
or under the terms of any subsequent version published by the license
|
|
||||||
steward.
|
|
||||||
|
|
||||||
10.3. Modified Versions
|
|
||||||
|
|
||||||
If you create software not governed by this License, and you want to
|
|
||||||
create a new license for such software, you may create and use a
|
|
||||||
modified version of this License if you rename the license and remove
|
|
||||||
any references to the name of the license steward (except to note that
|
|
||||||
such modified license differs from this License).
|
|
||||||
|
|
||||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
|
||||||
Licenses
|
|
||||||
|
|
||||||
If You choose to distribute Source Code Form that is Incompatible With
|
|
||||||
Secondary Licenses under the terms of this version of the License, the
|
|
||||||
notice described in Exhibit B of this License must be attached.
|
|
||||||
|
|
||||||
Exhibit A - Source Code Form License Notice
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
If it is not possible or desirable to put the notice in a particular
|
|
||||||
file, then You may include the notice in a location (such as a LICENSE
|
|
||||||
file in a relevant directory) where a recipient would be likely to look
|
|
||||||
for such a notice.
|
|
||||||
|
|
||||||
You may add additional accurate notices of copyright ownership.
|
|
||||||
|
|
||||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
||||||
defined by the Mozilla Public License, v. 2.0.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# asusctl
|
|
||||||
|
|
||||||
Requires `asusd` to be installed and running.
|
|
||||||
|
|
||||||
## build and install
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install
|
|
||||||
npm run build && gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
|
|
||||||
npm run build && gnome-extensions enable asusctl-gnome@asus-linux.org.zip
|
|
||||||
```
|
|
||||||
|
|
||||||
You will need to restart Gnome after installing or updating
|
|
||||||
|
|
||||||
## development
|
|
||||||
|
|
||||||
```
|
|
||||||
npm run build
|
|
||||||
gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
|
|
||||||
MUTTER_DEBUG_DUMMY_MODE_SPECS=1366x768 dbus-run-session -- gnome-shell --nested --wayland
|
|
||||||
```
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { build } from "esbuild";
|
|
||||||
import { exec } from "child_process";
|
|
||||||
import { copyFileSync, cpSync } from "fs";
|
|
||||||
import { resolve, dirname } from "path";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
import AdmZip from "adm-zip";
|
|
||||||
import metadata from "./src/metadata.json" assert { type: "json" };
|
|
||||||
|
|
||||||
build({
|
|
||||||
entryPoints: ["src/extension.ts"],
|
|
||||||
outdir: "dist",
|
|
||||||
bundle: true,
|
|
||||||
// Do not remove the functions `enable()`, `disable()` and `init()`
|
|
||||||
treeShaking: false,
|
|
||||||
// firefox60 // Since GJS 1.53.90
|
|
||||||
// firefox68 // Since GJS 1.63.90
|
|
||||||
// firefox78 // Since GJS 1.65.90
|
|
||||||
// firefox91 // Since GJS 1.71.1
|
|
||||||
// firefox102 // Since GJS 1.73.2
|
|
||||||
target: "firefox102",
|
|
||||||
//platform: "neutral",
|
|
||||||
platform: "node",
|
|
||||||
// mainFields: ['main'],
|
|
||||||
// conditions: ['require', 'default'],
|
|
||||||
format: "esm",
|
|
||||||
external: ["gi://*", "resource://*", "system", "gettext", "cairo"],
|
|
||||||
}).then(() => {
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = dirname(__filename);
|
|
||||||
|
|
||||||
const metaSrc = resolve(__dirname, "src/metadata.json");
|
|
||||||
const metaDist = resolve(__dirname, "dist/metadata.json");
|
|
||||||
const schemaSrc = resolve(__dirname, "schemas");
|
|
||||||
const schemaDist = resolve(__dirname, "dist/schemas");
|
|
||||||
const dbusXmlSrc = resolve(__dirname, "../../bindings/dbus-xml");
|
|
||||||
const dbusXmlDist = resolve(__dirname, "dist/resources/dbus");
|
|
||||||
const zipFilename = `${metadata.uuid}.zip`;
|
|
||||||
const zipDist = resolve(__dirname, zipFilename);
|
|
||||||
|
|
||||||
exec("glib-compile-schemas schemas/", (error, stdout, stderr) => {
|
|
||||||
console.log("stdout: " + stdout);
|
|
||||||
console.log("stderr: " + stderr);
|
|
||||||
});
|
|
||||||
|
|
||||||
copyFileSync(metaSrc, metaDist);
|
|
||||||
|
|
||||||
cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const zip = new AdmZip();
|
|
||||||
zip.addLocalFolder(resolve(__dirname, "dist"));
|
|
||||||
zip.writeZip(zipDist);
|
|
||||||
|
|
||||||
console.log(`Build complete. Zip file: ${zipFilename}\n`);
|
|
||||||
console.log(`Install with: gnome-extensions install ${zipFilename}`);
|
|
||||||
console.log(`Update with: gnome-extensions install ${zipFilename} --force`);
|
|
||||||
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`);
|
|
||||||
});
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
## Script to initialise dev-environment (types)
|
|
||||||
gv="44"
|
|
||||||
wd=${PWD}
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
rm -rf @types
|
|
||||||
|
|
||||||
# generate GJS from gir (this does not include the extensions)
|
|
||||||
echo "Generating GJS types from gir.."
|
|
||||||
npx ts-for-gir generate Shell-12 St-12 Gtk-4.0 \
|
|
||||||
-g /usr/share/gir-1.0 \
|
|
||||||
-g /usr/share/gnome-shell \
|
|
||||||
-g /usr/share/gnome-shell/gir-1.0 \
|
|
||||||
-g /usr/lib64/mutter-12 \
|
|
||||||
-t esm -o @types/Gjs
|
|
||||||
|
|
||||||
# get latest js (44) in this case and create the types for it
|
|
||||||
echo "Generating GJS Extension (Gex) types from extension source.."
|
|
||||||
mkdir -p ./_tmp/
|
|
||||||
cd ./_tmp
|
|
||||||
wget -q -O gnome-shell-js-${gv}.tar.gz https://gitlab.gnome.org/GNOME/gnome-shell/-/archive/gnome-${gv}/gnome-shell-gnome-${gv}.tar.gz?path=js
|
|
||||||
tar xf gnome-shell-js-${gv}.tar.gz
|
|
||||||
cd gnome-shell-gnome-${gv}-js
|
|
||||||
cat >tsconfig.json <<EOL
|
|
||||||
{
|
|
||||||
"include": ["js/ui/*"],
|
|
||||||
"exclude": [
|
|
||||||
"js/ui/shellDBus.js",
|
|
||||||
"node_modules",
|
|
||||||
"**/node_modules/*"
|
|
||||||
],
|
|
||||||
"compilerOptions": {
|
|
||||||
"allowJs": true,
|
|
||||||
"declaration": true,
|
|
||||||
"emitDeclarationOnly": true,
|
|
||||||
"outDir": "gex-types",
|
|
||||||
"declarationMap": true,
|
|
||||||
"lib": ["es2019"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOL
|
|
||||||
npx tsc
|
|
||||||
cd ${wd}
|
|
||||||
mv ./_tmp/gnome-shell-gnome-${gv}-js/gex-types @types/Gex
|
|
||||||
# rm -rf ./_tmp/
|
|
||||||
|
|
||||||
echo "done."
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
-2747
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "asusctl-gnome",
|
|
||||||
"version": "5.0.0-RC1",
|
|
||||||
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/extension.js",
|
|
||||||
"scripts": {
|
|
||||||
"clear": "rm -rf dist",
|
|
||||||
"compile": "tsc --build tsconfig.json",
|
|
||||||
"build:app": "node esbuild.js",
|
|
||||||
"build": "yarn run clear && yarn run build:app",
|
|
||||||
"validate": "tsc --noEmit",
|
|
||||||
"generate:gir-types": "ts-for-gir generate",
|
|
||||||
"check:types": "tsc --build tsconfig.types.json",
|
|
||||||
"lint": "eslint .",
|
|
||||||
"format": "prettier . -w"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@girs/gnome-shell": "^45.0.0-beta2",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
|
||||||
"@typescript-eslint/parser": "^5.60.1",
|
|
||||||
"adm-zip": "^0.5.10",
|
|
||||||
"esbuild": "^0.19.5",
|
|
||||||
"eslint": "^8.51.0",
|
|
||||||
"eslint-config-prettier": "^9.0.0",
|
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
|
||||||
"prettier": "^3.0.3",
|
|
||||||
"typescript": "^5.2.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@girs/gjs": "^3.2.5",
|
|
||||||
"@girs/gobject-2.0": "^2.78.0-3.2.5",
|
|
||||||
"@girs/st-13": "^13.0.0-3.2.5"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+ssh://git@gitlab.com/asus-linux/asusctl.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"gnome-shell",
|
|
||||||
"extension",
|
|
||||||
"asusctl",
|
|
||||||
"asus",
|
|
||||||
"rog",
|
|
||||||
"gnome",
|
|
||||||
"gjs",
|
|
||||||
"typescript"
|
|
||||||
],
|
|
||||||
"author": "Armas Spann, Marco Laux, Luke Jones",
|
|
||||||
"license": "MPL-2",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://gitlab.com/asus-linux/asusctl/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://gitlab.com/asus-linux/asusctl/desktop-extensions/gnome#readme"
|
|
||||||
}
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<schemalist gettext-domain="AsusctlGnomeExtension">
|
|
||||||
<schema id="org.gnome.shell.extensions.asusctl-gnome" path="/org/gnome/shell/extensions/asusctl-gnome/" >
|
|
||||||
<key type="b" name="mini-led-enabled">
|
|
||||||
<default>false</default>
|
|
||||||
</key>
|
|
||||||
<key type="b" name="panel-od-enabled">
|
|
||||||
<default>false</default>
|
|
||||||
</key>
|
|
||||||
<key type="b" name="anime-power">
|
|
||||||
<default>false</default>
|
|
||||||
</key>
|
|
||||||
<key type="b" name="anime-builtins">
|
|
||||||
<default>false</default>
|
|
||||||
</key>
|
|
||||||
<key name="charge-level" type="u">
|
|
||||||
<range min="20" max="100"/>
|
|
||||||
<default>100</default>
|
|
||||||
</key>
|
|
||||||
<key type="s" name="primary-quickmenu-toggle">
|
|
||||||
<default>"mini-led"</default>
|
|
||||||
</key>
|
|
||||||
</schema>
|
|
||||||
</schemalist>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../bindings/ts
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import * as platform from "./bindings/platform";
|
|
||||||
import { AsusQuickToggle } from "./modules/rog_quick_toggle";
|
|
||||||
import { AsusMenuToggle } from "./modules/rog_menu_toggle";
|
|
||||||
import { AsusIndicator } from "./modules/rog_indicator";
|
|
||||||
import { AsusSlider } from "./modules/rog_slider_100pc";
|
|
||||||
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
|
|
||||||
import { DbusBase } from "./modules/dbus_proxy";
|
|
||||||
import { main } from "@girs/gnome-shell/ui";
|
|
||||||
|
|
||||||
export const uuid = "asusctl-gnome@asus-linux.org";
|
|
||||||
export default class AsusExtension extends Extension {
|
|
||||||
// public dbus_aura: AuraDbus = new AuraDbus;
|
|
||||||
// public dbus_anime: AnimeDbus = new AnimeDbus;
|
|
||||||
public dbus_platform: DbusBase | undefined;
|
|
||||||
public dbus_anime: DbusBase | undefined;
|
|
||||||
|
|
||||||
private individual = false;
|
|
||||||
public supported_properties!: platform.Properties;
|
|
||||||
public supported_interfaces: string[] = [];
|
|
||||||
private feature_menu = null;
|
|
||||||
private panel_od = null;
|
|
||||||
private mini_led = null;
|
|
||||||
private anime_display = null;
|
|
||||||
private anime_builtins = null;
|
|
||||||
private charge_thres = null;
|
|
||||||
// private _feature: typeof FeatureMenuToggle;
|
|
||||||
|
|
||||||
async enable() {
|
|
||||||
log(this.path);
|
|
||||||
|
|
||||||
if (this.dbus_platform == undefined) {
|
|
||||||
this.dbus_platform = new DbusBase("org-asuslinux-platform-4.xml", "/org/asuslinux/Platform");
|
|
||||||
await this.dbus_platform.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.dbus_anime == undefined) {
|
|
||||||
this.dbus_anime = new DbusBase("org-asuslinux-anime-4.xml", "/org/asuslinux/Anime");
|
|
||||||
await this.dbus_anime.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
|
|
||||||
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
|
|
||||||
log(this.supported_interfaces);
|
|
||||||
log(this.supported_properties);
|
|
||||||
|
|
||||||
// new AsusIndicator("selection-mode-symbolic", "mini-led-enabled");
|
|
||||||
// new AsusIndicator("selection-mode-symbolic", "panel-od-enabled");
|
|
||||||
|
|
||||||
if (!this.individual) {
|
|
||||||
if (this.feature_menu == null)
|
|
||||||
this.feature_menu = new FeatureMenuToggle(this.dbus_platform, this.dbus_anime);
|
|
||||||
} else {
|
|
||||||
if (this.supported_properties.includes("PanelOd") && this.dbus_platform.proxy.PanelOd != null)
|
|
||||||
if (this.panel_od == null) {
|
|
||||||
this.panel_od = new AsusQuickToggle(
|
|
||||||
this.dbus_platform,
|
|
||||||
"PanelOd",
|
|
||||||
"panel-od-enabled",
|
|
||||||
"Panel Overdrive",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.supported_properties.includes("MiniLed") && this.dbus_platform.proxy.MiniLed != null)
|
|
||||||
if (this.mini_led == null) {
|
|
||||||
this.mini_led = new AsusQuickToggle(
|
|
||||||
this.dbus_platform,
|
|
||||||
"MiniLed",
|
|
||||||
"mini-led-enabled",
|
|
||||||
"Mini-LED",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.supported_interfaces.includes("Anime") &&
|
|
||||||
this.dbus_anime.proxy.EnableDisplay != null
|
|
||||||
)
|
|
||||||
if (this.anime_display == null) {
|
|
||||||
this.anime_display = new AsusQuickToggle(
|
|
||||||
this.dbus_anime,
|
|
||||||
"EnableDisplay",
|
|
||||||
"anime-power",
|
|
||||||
"AniMe Display",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.supported_interfaces.includes("Anime") &&
|
|
||||||
this.dbus_anime.proxy.BuiltinsEnabled != null
|
|
||||||
)
|
|
||||||
if (this.anime_builtins == null) {
|
|
||||||
this.anime_builtins = new AsusQuickToggle(
|
|
||||||
this.dbus_anime,
|
|
||||||
"BuiltinsEnabled",
|
|
||||||
"anime-builtins",
|
|
||||||
"Use builtins",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.supported_properties.includes("ChargeControlEndThreshold") &&
|
|
||||||
this.dbus_platform.proxy.ChargeControlEndThreshold != null
|
|
||||||
)
|
|
||||||
if (this.charge_thres == null) {
|
|
||||||
this.charge_thres = new AsusSlider(
|
|
||||||
this.dbus_platform,
|
|
||||||
"ChargeControlEndThreshold",
|
|
||||||
"charge-level",
|
|
||||||
"Charge Level",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
this.dbus_platform?.stop();
|
|
||||||
this.dbus_anime?.stop();
|
|
||||||
|
|
||||||
this.feature_menu?.destroy();
|
|
||||||
feature_menu?.destroy();
|
|
||||||
panel_od?.destroy();
|
|
||||||
mini_led?.destroy();
|
|
||||||
anime_display?.destroy();
|
|
||||||
anime_builtins?.destroy();
|
|
||||||
charge_thres?.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "asusctl-gnome",
|
|
||||||
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
|
|
||||||
"uuid": "asusctl-gnome@asus-linux.org",
|
|
||||||
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
|
|
||||||
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
|
|
||||||
"version": "4.3.2",
|
|
||||||
"shell-version": ["45"]
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import { DbusBase } from "../dbus_proxy";
|
|
||||||
import {
|
|
||||||
DeviceState,
|
|
||||||
AnimBooting,
|
|
||||||
Brightness,
|
|
||||||
AnimAwake,
|
|
||||||
AnimSleeping,
|
|
||||||
AnimShutdown,
|
|
||||||
} from "../../bindings/anime";
|
|
||||||
|
|
||||||
export class AnimeDbus extends DbusBase {
|
|
||||||
deviceState: DeviceState = {
|
|
||||||
display_enabled: false,
|
|
||||||
display_brightness: Brightness.Med,
|
|
||||||
builtin_anims_enabled: false,
|
|
||||||
builtin_anims: {
|
|
||||||
boot: AnimBooting.GlitchConstruction,
|
|
||||||
awake: AnimAwake.BinaryBannerScroll,
|
|
||||||
sleep: AnimSleeping.BannerSwipe,
|
|
||||||
shutdown: AnimShutdown.GlitchOut,
|
|
||||||
},
|
|
||||||
off_when_unplugged: false,
|
|
||||||
off_when_suspended: false,
|
|
||||||
off_when_lid_closed: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: interface or something to enforce requirement of "sync()" method
|
|
||||||
public notifyAnimeStateSubscribers: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseData(data: any) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
this.deviceState.display_enabled = data[0];
|
|
||||||
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
|
|
||||||
this.deviceState.builtin_anims_enabled = data[2];
|
|
||||||
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
|
|
||||||
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
|
|
||||||
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
|
|
||||||
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][3] as AnimShutdown];
|
|
||||||
this.deviceState.off_when_unplugged = data[4];
|
|
||||||
this.deviceState.off_when_suspended = data[5];
|
|
||||||
this.deviceState.off_when_lid_closed = data[6];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getDeviceState() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
// janky shit going on with DeviceStateSync
|
|
||||||
this._parseData(this.dbus_proxy.DeviceStateSync());
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: display_enabled: " + this.deviceState.display_enabled);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: display_brightness: " + this.deviceState.display_brightness);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: builtin_anims_enabled: " + this.deviceState.builtin_anims_enabled);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: builtin_anims: " + this.deviceState.builtin_anims);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: off_when_unplugged: " + this.deviceState.off_when_unplugged);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: off_when_suspended: " + this.deviceState.off_when_suspended);
|
|
||||||
//@ts-ignore
|
|
||||||
log("Anime Matrix: off_when_lid_closed: " + this.deviceState.off_when_lid_closed);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch DeviceState!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.deviceState;
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
await super.start();
|
|
||||||
this.getDeviceState();
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyDeviceState",
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(proxy: any = null, name: string, data: string) => {
|
|
||||||
if (proxy) {
|
|
||||||
// idiot xml parsing mneans the get is not nested while this is
|
|
||||||
this._parseData(data[0]);
|
|
||||||
this.notifyAnimeStateSubscribers.forEach((sub) => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
import {
|
|
||||||
AuraDevRog1,
|
|
||||||
AuraDevTuf,
|
|
||||||
AuraDevice,
|
|
||||||
AuraEffect,
|
|
||||||
AuraModeNum,
|
|
||||||
AuraPower,
|
|
||||||
AuraPowerDev,
|
|
||||||
AuraZone,
|
|
||||||
Direction,
|
|
||||||
PowerZones,
|
|
||||||
Speed,
|
|
||||||
} from "../../bindings/aura";
|
|
||||||
import { DbusBase } from "./base";
|
|
||||||
|
|
||||||
export class AuraDbus extends DbusBase {
|
|
||||||
public device: AuraDevice = AuraDevice.Unknown;
|
|
||||||
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
|
|
||||||
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map();
|
|
||||||
public leds_powered: AuraPowerDev = {
|
|
||||||
tuf: [],
|
|
||||||
old_rog: [],
|
|
||||||
rog: {
|
|
||||||
keyboard: {
|
|
||||||
zone: PowerZones.Keyboard,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false,
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
zone: PowerZones.Logo,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false,
|
|
||||||
},
|
|
||||||
lightbar: {
|
|
||||||
zone: PowerZones.Lightbar,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false,
|
|
||||||
},
|
|
||||||
lid: {
|
|
||||||
zone: PowerZones.Lid,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false,
|
|
||||||
},
|
|
||||||
rear_glow: {
|
|
||||||
zone: PowerZones.RearGlow,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// TODO: interface or something to enforce requirement of "sync()" method
|
|
||||||
public notifyAuraModeSubscribers: any[] = [];
|
|
||||||
public notifyAuraPowerSubscribers: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
|
|
||||||
}
|
|
||||||
|
|
||||||
public getDevice() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED device: " + this.device);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parsePowerStates(data: any[]) {
|
|
||||||
const power: AuraPowerDev = this.leds_powered;
|
|
||||||
|
|
||||||
power.tuf = data[0].map((value: string) => {
|
|
||||||
return AuraDevTuf[value as AuraDevTuf];
|
|
||||||
});
|
|
||||||
power.old_rog = data[1].map((value: string) => {
|
|
||||||
return AuraDevRog1[value as AuraDevRog1];
|
|
||||||
});
|
|
||||||
power.rog = {
|
|
||||||
keyboard: {
|
|
||||||
zone: PowerZones[data[2][0][0] as PowerZones],
|
|
||||||
boot: data[2][0][1],
|
|
||||||
awake: data[2][0][2],
|
|
||||||
sleep: data[2][0][3],
|
|
||||||
shutdown: data[2][0][4],
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
zone: PowerZones[data[2][1][0] as PowerZones],
|
|
||||||
boot: data[2][1][1],
|
|
||||||
awake: data[2][1][2],
|
|
||||||
sleep: data[2][1][3],
|
|
||||||
shutdown: data[2][1][4],
|
|
||||||
},
|
|
||||||
lightbar: {
|
|
||||||
zone: PowerZones[data[2][2][0] as PowerZones],
|
|
||||||
boot: data[2][2][1],
|
|
||||||
awake: data[2][2][2],
|
|
||||||
sleep: data[2][2][3],
|
|
||||||
shutdown: data[2][2][4],
|
|
||||||
},
|
|
||||||
lid: {
|
|
||||||
zone: PowerZones[data[2][3][0] as PowerZones],
|
|
||||||
boot: data[2][3][1],
|
|
||||||
awake: data[2][3][2],
|
|
||||||
sleep: data[2][3][3],
|
|
||||||
shutdown: data[2][3][4],
|
|
||||||
},
|
|
||||||
rear_glow: {
|
|
||||||
zone: PowerZones[data[2][4][0] as PowerZones],
|
|
||||||
boot: data[2][4][1],
|
|
||||||
awake: data[2][4][2],
|
|
||||||
sleep: data[2][4][3],
|
|
||||||
shutdown: data[2][4][4],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLedPower() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
const data = this.dbus_proxy.LedPowerSync();
|
|
||||||
this.leds_powered = this._parsePowerStates(data);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power tuf: " + this.leds_powered.tuf);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power x1866: " + this.leds_powered.old_rog);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power x19b6: " + this.leds_powered.rog);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLedMode() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
|
|
||||||
//@ts-ignore
|
|
||||||
log("Current LED mode:", this.current_aura_mode);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setLedMode(mode: AuraEffect) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.dbus_proxy.SetLedModeSync([
|
|
||||||
mode.mode,
|
|
||||||
mode.zone,
|
|
||||||
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
|
|
||||||
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
|
|
||||||
mode.speed,
|
|
||||||
mode.direction,
|
|
||||||
]);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseAuraEffect(data: any[]) {
|
|
||||||
const aura: AuraEffect = {
|
|
||||||
mode: AuraModeNum[data[0] as AuraModeNum],
|
|
||||||
zone: AuraZone[data[1] as AuraZone],
|
|
||||||
colour1: {
|
|
||||||
r: parseInt(data[2][0]),
|
|
||||||
g: parseInt(data[2][1]),
|
|
||||||
b: parseInt(data[2][2]),
|
|
||||||
},
|
|
||||||
colour2: {
|
|
||||||
r: parseInt(data[3][0]),
|
|
||||||
g: parseInt(data[3][1]),
|
|
||||||
b: parseInt(data[3][2]),
|
|
||||||
},
|
|
||||||
speed: Speed[data[4] as Speed],
|
|
||||||
direction: Direction[data[5] as Direction],
|
|
||||||
};
|
|
||||||
return aura;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a list of the available modes, and the current settings for each
|
|
||||||
public getLedModes() {
|
|
||||||
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
const _data = this.dbus_proxy.LedModesSync();
|
|
||||||
for (const key in _data[0]) {
|
|
||||||
const data = _data[0][key];
|
|
||||||
const aura: AuraEffect = this._parseAuraEffect(data);
|
|
||||||
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [key, value] of this.aura_modes) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(key, value.zone, value.colour1.r, value.speed, value.direction);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
await super.start();
|
|
||||||
this.getDevice();
|
|
||||||
this.getLedPower();
|
|
||||||
this.getLedMode();
|
|
||||||
this.getLedModes();
|
|
||||||
|
|
||||||
//@ts-ignore
|
|
||||||
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal("NotifyLed", (proxy: any = null, name: string, data: any) => {
|
|
||||||
if (proxy) {
|
|
||||||
const aura: AuraEffect = this._parseAuraEffect(data[0]);
|
|
||||||
this.current_aura_mode = aura.mode;
|
|
||||||
this.aura_modes.set(aura.mode, aura);
|
|
||||||
//@ts-ignore
|
|
||||||
log(
|
|
||||||
"LED data has changed to ",
|
|
||||||
aura.mode,
|
|
||||||
aura.zone,
|
|
||||||
aura.colour1.r,
|
|
||||||
aura.speed,
|
|
||||||
aura.direction,
|
|
||||||
);
|
|
||||||
this.notifyAuraModeSubscribers.forEach((sub) => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyPowerStates",
|
|
||||||
(proxy: any = null, name: string, data: any) => {
|
|
||||||
if (proxy) {
|
|
||||||
const power: AuraPowerDev = this._parsePowerStates(data[0]);
|
|
||||||
this.leds_powered = power;
|
|
||||||
switch (this.device) {
|
|
||||||
case AuraDevice.Tuf:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.tuf);
|
|
||||||
break;
|
|
||||||
case AuraDevice.X1854:
|
|
||||||
case AuraDevice.X1869:
|
|
||||||
case AuraDevice.X18c6:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.old_rog);
|
|
||||||
break;
|
|
||||||
case AuraDevice.X19b6:
|
|
||||||
case AuraDevice.X1a30:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.rog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.rog);
|
|
||||||
this.notifyAuraPowerSubscribers.forEach((sub) => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Supported DBus initialization failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import { Gio } from "@girs/gio-2.0";
|
|
||||||
import { GLib } from "@girs/glib-2.0";
|
|
||||||
import { imports } from "@girs/gjs";
|
|
||||||
|
|
||||||
// Reads the contents of a file contained in the global resources archive. The data
|
|
||||||
// is returned as a string.
|
|
||||||
export function getStringResource(path: string | null) {
|
|
||||||
const data = Gio.resources_lookup_data(path, 0);
|
|
||||||
return new TextDecoder().decode(data.get_data()?.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DbusBase {
|
|
||||||
proxy!: Gio.DBusProxy;
|
|
||||||
connected = false;
|
|
||||||
ifaceXml = "";
|
|
||||||
dbus_path = "";
|
|
||||||
|
|
||||||
constructor(file_name: string, dbus_path: string) {
|
|
||||||
let extensionObject = Extension.lookupByUUID("asusctl-gnome@asus-linux.org");
|
|
||||||
const path = extensionObject?.path + "/resources/dbus/" + file_name;
|
|
||||||
const [ok, data] = GLib.file_get_contents(path);
|
|
||||||
if (!ok) {
|
|
||||||
throw new Error("could not read interface file");
|
|
||||||
}
|
|
||||||
this.ifaceXml = imports.byteArray.toString(data);
|
|
||||||
this.dbus_path = dbus_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Starting ${this.dbus_path} dbus module`);
|
|
||||||
try {
|
|
||||||
log(this.ifaceXml);
|
|
||||||
this.proxy = Gio.DBusProxy.makeProxyWrapper(this.ifaceXml)(
|
|
||||||
Gio.DBus.system,
|
|
||||||
"org.asuslinux.Daemon",
|
|
||||||
this.dbus_path,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.connected = true;
|
|
||||||
//@ts-ignore
|
|
||||||
log(`${this.dbus_path} client started successfully.`);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
logError(`${this.xml_resource} dbus init failed!`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Stopping ${this.xml_resource} dbus module`);
|
|
||||||
|
|
||||||
if (this.connected && this.proxy != undefined) {
|
|
||||||
this.proxy.run_dispose();
|
|
||||||
this.proxy = undefined;
|
|
||||||
this.connected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isRunning(): boolean {
|
|
||||||
return this.connected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import * as Main from "resource:///org/gnome/shell/ui/main.js";
|
|
||||||
import { QuickToggle } from "resource:///org/gnome/shell/ui/quickSettings.js";
|
|
||||||
|
|
||||||
export function addQuickSettingsItems(items: [typeof QuickToggle], width = 1) {
|
|
||||||
const QuickSettingsMenu = Main.panel.statusArea.quickSettings;
|
|
||||||
items.forEach((item) => QuickSettingsMenu.menu.addItem(item, width));
|
|
||||||
// Ensure the tile(s) are above the background apps menu
|
|
||||||
for (const item of items) {
|
|
||||||
QuickSettingsMenu.menu._grid.set_child_below_sibling(
|
|
||||||
item,
|
|
||||||
QuickSettingsMenu._backgroundApps.quickSettingsItems[0],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
import { AuraDbus } from "../dbus/aura";
|
|
||||||
import { AuraEffect, AuraModeNum } from "../../bindings/aura";
|
|
||||||
import GObject from "gi://GObject";
|
|
||||||
|
|
||||||
import * as PopupMenu from "resource:///org/gnome/shell/ui/popupMenu.js";
|
|
||||||
import * as QuickSettings from "resource:///org/gnome/shell/ui/quickSettings.js";
|
|
||||||
|
|
||||||
export const AuraMenuToggle = GObject.registerClass(
|
|
||||||
class AuraMenuToggle extends QuickSettings.QuickMenuToggle {
|
|
||||||
private _dbus_aura: AuraDbus;
|
|
||||||
private _last_mode: AuraModeNum = AuraModeNum.Static;
|
|
||||||
|
|
||||||
constructor(dbus_aura: AuraDbus) {
|
|
||||||
super({
|
|
||||||
title: "Aura Modes",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_aura = dbus_aura;
|
|
||||||
|
|
||||||
this.connectObject(this);
|
|
||||||
|
|
||||||
this.menu.setHeader("selection-mode-symbolic", this._dbus_aura.current_aura_mode);
|
|
||||||
|
|
||||||
this._itemsSection = new PopupMenu.PopupMenuSection();
|
|
||||||
|
|
||||||
this._dbus_aura.aura_modes.forEach((mode, key) => {
|
|
||||||
this._itemsSection.addAction(
|
|
||||||
key,
|
|
||||||
() => {
|
|
||||||
this._dbus_aura.setLedMode(mode);
|
|
||||||
this.sync();
|
|
||||||
},
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.menu.addMenuItem(this._itemsSection);
|
|
||||||
|
|
||||||
// Add an entry-point for more settings
|
|
||||||
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
||||||
// const settingsItem = this.menu.addAction("More Settings",
|
|
||||||
// () => ExtensionUtils.openPrefs());
|
|
||||||
// // Ensure the settings are unavailable when the screen is locked
|
|
||||||
// settingsItem.visible = Main.sessionMode.allowSettings;
|
|
||||||
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"clicked",
|
|
||||||
() => {
|
|
||||||
let mode: AuraEffect | undefined;
|
|
||||||
if (this._dbus_aura.current_aura_mode == AuraModeNum.Static) {
|
|
||||||
mode = this._dbus_aura.aura_modes.get(this._last_mode);
|
|
||||||
} else {
|
|
||||||
mode = this._dbus_aura.aura_modes.get(AuraModeNum.Static);
|
|
||||||
}
|
|
||||||
if (mode != undefined) {
|
|
||||||
this._dbus_aura.setLedMode(mode);
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
this,
|
|
||||||
);
|
|
||||||
|
|
||||||
this._dbus_aura.notifyAuraModeSubscribers.push(this);
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const checked = this._dbus_aura.current_aura_mode != AuraModeNum.Static;
|
|
||||||
this.title = this._dbus_aura.current_aura_mode;
|
|
||||||
if (
|
|
||||||
this._last_mode != this._dbus_aura.current_aura_mode &&
|
|
||||||
this._dbus_aura.current_aura_mode != AuraModeNum.Static
|
|
||||||
) {
|
|
||||||
this._last_mode = this._dbus_aura.current_aura_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.checked !== checked) this.set({ checked });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import { quickSettings, popupMenu } from "@girs/gnome-shell/ui";
|
|
||||||
import { GObject } from "@girs/gobject-2.0";
|
|
||||||
|
|
||||||
import { DbusBase } from "../../modules/dbus_proxy";
|
|
||||||
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
|
|
||||||
import * as AsusExtension from "../../extension";
|
|
||||||
import * as platform from "../../bindings/platform";
|
|
||||||
import { uuid } from "../../extension";
|
|
||||||
import { AsusMenuToggle } from "../rog_menu_toggle";
|
|
||||||
|
|
||||||
export const FeatureMenuToggle = GObject.registerClass(
|
|
||||||
class FeatureMenuToggle extends quickSettings.QuickMenuToggle {
|
|
||||||
private dbus_platform: DbusBase;
|
|
||||||
private dbus_anime: DbusBase;
|
|
||||||
private last_selection = "mini-led";
|
|
||||||
private supported_properties!: platform.Properties;
|
|
||||||
private supported_interfaces: string[] = [];
|
|
||||||
|
|
||||||
private miniLed?: typeof AsusMenuToggle;
|
|
||||||
private panelOd?: typeof AsusMenuToggle;
|
|
||||||
private animeDisplayPower?: typeof AsusMenuToggle;
|
|
||||||
private animePowersaveAnim?: typeof AsusMenuToggle;
|
|
||||||
_itemsSection: popupMenu.PopupMenuSection;
|
|
||||||
|
|
||||||
constructor(dbus_platform: DbusBase, dbus_anime: DbusBase) {
|
|
||||||
super({
|
|
||||||
label: "Laptop",
|
|
||||||
toggle_mode: true,
|
|
||||||
icon_name: "selection-mode-symbolic",
|
|
||||||
});
|
|
||||||
this.label = "Laptop";
|
|
||||||
this.title = "Laptop";
|
|
||||||
this.dbus_platform = dbus_platform;
|
|
||||||
this.dbus_anime = dbus_anime;
|
|
||||||
|
|
||||||
this.menu.setHeader("selection-mode-symbolic", "Laptop features");
|
|
||||||
|
|
||||||
this.last_selection = Extension.lookupByUUID(AsusExtension.uuid)
|
|
||||||
?.getSettings()
|
|
||||||
.get_string("primary-quickmenu-toggle")!;
|
|
||||||
|
|
||||||
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
|
|
||||||
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
|
|
||||||
|
|
||||||
// TODO: temporary block
|
|
||||||
if (this.last_selection == "mini-led" && !this.supported_properties.includes("MiniLed")) {
|
|
||||||
this.last_selection = "panel-od";
|
|
||||||
} else if (
|
|
||||||
this.last_selection == "panel-od" &&
|
|
||||||
!this.supported_properties.includes("PanelOd")
|
|
||||||
) {
|
|
||||||
this.last_selection = "anime-power";
|
|
||||||
} else if (
|
|
||||||
this.last_selection == "anime-power" &&
|
|
||||||
!this.supported_interfaces.includes("Anime")
|
|
||||||
) {
|
|
||||||
this.last_selection = "mini-led";
|
|
||||||
} else if (this.last_selection.length == 0) {
|
|
||||||
this.last_selection = "panel-od";
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsusExtension.extension._settings.connect('changed::primary-quickmenu-toggle', this.sync);
|
|
||||||
Extension.lookupByUUID(uuid)
|
|
||||||
?.getSettings()
|
|
||||||
.set_string("primary-quickmenu-toggle", this.last_selection);
|
|
||||||
|
|
||||||
this._itemsSection = new popupMenu.PopupMenuSection();
|
|
||||||
if (this.supported_properties.includes("MiniLed")) {
|
|
||||||
if (this.miniLed == null) {
|
|
||||||
this.miniLed = new AsusMenuToggle(
|
|
||||||
this.dbus_platform,
|
|
||||||
"MiniLed",
|
|
||||||
"mini-led-enabled",
|
|
||||||
"Mini-LED Enabled",
|
|
||||||
);
|
|
||||||
this._itemsSection.addMenuItem(this.miniLed, 0);
|
|
||||||
this.miniLed.toggle_callback = () => {
|
|
||||||
this.last_selection = "mini-led";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.supported_properties.includes("PanelOd")) {
|
|
||||||
if (this.panelOd == null) {
|
|
||||||
this.panelOd = new AsusMenuToggle(
|
|
||||||
this.dbus_platform,
|
|
||||||
"PanelOd",
|
|
||||||
"panel-od-enabled",
|
|
||||||
"Panel Overdrive Enabled",
|
|
||||||
);
|
|
||||||
this._itemsSection.addMenuItem(this.panelOd, 1);
|
|
||||||
this.panelOd.toggle_callback = () => {
|
|
||||||
this.last_selection = "panel-od";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.supported_interfaces.includes("Anime")) {
|
|
||||||
if (this.animeDisplayPower == null) {
|
|
||||||
this.animeDisplayPower = new AsusMenuToggle(
|
|
||||||
this.dbus_anime,
|
|
||||||
"EnableDisplay",
|
|
||||||
"anime-power",
|
|
||||||
"AniMe Display Enabled",
|
|
||||||
);
|
|
||||||
this._itemsSection.addMenuItem(this.animeDisplayPower, 2);
|
|
||||||
this.animeDisplayPower.toggle_callback = () => {
|
|
||||||
this.last_selection = "anime-power";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.animePowersaveAnim == null) {
|
|
||||||
this.animePowersaveAnim = new AsusMenuToggle(
|
|
||||||
this.dbus_anime,
|
|
||||||
"BuiltinsEnabled",
|
|
||||||
"anime-builtins",
|
|
||||||
"AniMe Built-in Animations",
|
|
||||||
);
|
|
||||||
this._itemsSection.addMenuItem(this.animePowersaveAnim, 3);
|
|
||||||
this.animePowersaveAnim.toggle_callback = () => {
|
|
||||||
this.last_selection = "anime-builtins";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"clicked",
|
|
||||||
() => {
|
|
||||||
this._toggle();
|
|
||||||
},
|
|
||||||
this,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.menu.addMenuItem(this._itemsSection, 0);
|
|
||||||
|
|
||||||
this.dbus_platform?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
|
||||||
//const properties = changed.deepUnpack();
|
|
||||||
this.sync();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.dbus_anime?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
|
||||||
//const properties = changed.deepUnpack();
|
|
||||||
this.sync();
|
|
||||||
});
|
|
||||||
|
|
||||||
// // Add an entry-point for more extension._settings
|
|
||||||
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
||||||
// const settingsItem = this.menu.addAction("More Settings",
|
|
||||||
// () => ExtensionUtils.openPrefs());
|
|
||||||
// // Ensure the extension._settings are unavailable when the screen is locked
|
|
||||||
// settingsItem.visible = Main.sessionMode.allowSettings;
|
|
||||||
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggle() {
|
|
||||||
if (this.last_selection == "mini-led" && this.miniLed != null) {
|
|
||||||
if (this.checked !== this.dbus_platform.proxy.MiniLed)
|
|
||||||
this.dbus_platform.proxy.MiniLed = this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "panel-od" && this.panelOd != null) {
|
|
||||||
if (this.checked !== this.dbus_platform.proxy.PanelOd) {
|
|
||||||
this.dbus_platform.proxy.PanelOd = this.checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
|
|
||||||
if (this.checked !== this.dbus_anime.proxy.EnableDisplay)
|
|
||||||
this.dbus_anime.proxy.EnableDisplay = this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
|
|
||||||
if (this.checked !== this.dbus_anime.proxy.BuiltinsEnabled)
|
|
||||||
this.dbus_anime.proxy.BuiltinsEnabled = this.checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
let checked = false;
|
|
||||||
if (this.last_selection == "mini-led" && this.miniLed != null) {
|
|
||||||
this.title = this.miniLed.title;
|
|
||||||
checked = this.dbus_platform.proxy.MiniLed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "panel-od" && this.panelOd != null) {
|
|
||||||
this.title = this.panelOd.title;
|
|
||||||
checked = this.dbus_platform.proxy.PanelOd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
|
|
||||||
this.title = this.animeDisplayPower.title;
|
|
||||||
checked = this.dbus_anime.proxy.EnableDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
|
|
||||||
this.title = this.animePowersaveAnim.title;
|
|
||||||
checked = this.dbus_anime.proxy.BuiltinsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (this.animePowersaveAnim != null) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.checked !== checked) this.set({ checked });
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
// this.panelOd?.destroy();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import { quickSettings, main } from "@girs/gnome-shell/ui";
|
|
||||||
import { Gio } from "@girs/gio-2.0";
|
|
||||||
import { GObject } from "@girs/gobject-2.0";
|
|
||||||
import { uuid } from "../extension";
|
|
||||||
//import { DbusBase } from '../dbus_proxy';
|
|
||||||
|
|
||||||
export const AsusIndicator = GObject.registerClass(
|
|
||||||
class AsusIndicator extends quickSettings.SystemIndicator {
|
|
||||||
private _indicator: any;
|
|
||||||
private _settings: Gio.Settings | undefined;
|
|
||||||
|
|
||||||
constructor(icon_name: string, setting_name: string) {
|
|
||||||
super();
|
|
||||||
// Create an icon for the indicator
|
|
||||||
this._indicator = this._addIndicator();
|
|
||||||
this._indicator.icon_name = icon_name;
|
|
||||||
|
|
||||||
// Showing an indicator when the feature is enabled
|
|
||||||
this._settings = Extension.lookupByUUID(uuid)?.getSettings();
|
|
||||||
this._settings?.bind(setting_name, this._indicator, "visible", Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
main.panel.statusArea.quickSettings.addExternalIndicator(this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
import { popupMenu } from "@girs/gnome-shell/ui";
|
|
||||||
import { GObject } from "@girs/gobject-2.0";
|
|
||||||
import { DbusBase } from "./dbus_proxy";
|
|
||||||
|
|
||||||
export const AsusMenuToggle = GObject.registerClass(
|
|
||||||
class AsusMenuToggle extends popupMenu.PopupSwitchMenuItem {
|
|
||||||
public title: string = "";
|
|
||||||
dbus!: DbusBase;
|
|
||||||
prop_name: string = "";
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
|
||||||
super(title, true);
|
|
||||||
this.prop_name = prop_name;
|
|
||||||
this.dbus = dbus;
|
|
||||||
this.title = title;
|
|
||||||
|
|
||||||
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
|
||||||
const properties = changed.deepUnpack();
|
|
||||||
// .find() fails on some shit for some reason
|
|
||||||
for (const v of Object.entries(properties)) {
|
|
||||||
if (v[0] == this.prop_name) {
|
|
||||||
this.sync();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connectObject("toggled", () => this._toggleMode(), this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
// hacky shit, index to get base object property and set it
|
|
||||||
const state = this.dbus.proxy[this.prop_name];
|
|
||||||
if (this.state !== state) this.dbus.proxy[this.prop_name] = this.state;
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const state = this.dbus.proxy[this.prop_name];
|
|
||||||
if (this.state !== state) this.setToggleState(state);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import { addQuickSettingsItems } from "./helpers";
|
|
||||||
import { quickSettings } from "@girs/gnome-shell/ui";
|
|
||||||
import { Gio } from "@girs/gio-2.0";
|
|
||||||
import { GObject } from "@girs/gobject-2.0";
|
|
||||||
import { uuid } from "../extension";
|
|
||||||
import { DbusBase } from "./dbus_proxy";
|
|
||||||
|
|
||||||
export const AsusQuickToggle = GObject.registerClass(
|
|
||||||
class AsusQuickToggle extends quickSettings.QuickToggle {
|
|
||||||
dbus!: DbusBase;
|
|
||||||
prop_name: string = "";
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
|
||||||
super({
|
|
||||||
label: title,
|
|
||||||
icon_name: "selection-mode-symbolic",
|
|
||||||
toggle_mode: true,
|
|
||||||
});
|
|
||||||
this.prop_name = prop_name;
|
|
||||||
this.label = title;
|
|
||||||
this.dbus = dbus;
|
|
||||||
|
|
||||||
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
|
||||||
const properties = changed.deepUnpack();
|
|
||||||
// .find() fails on some shit for some reason
|
|
||||||
for (const v of Object.entries(properties)) {
|
|
||||||
if (v[0] == this.prop_name) {
|
|
||||||
const checked = v[1].unpack();
|
|
||||||
if (this.checked !== checked) this.checked = checked;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connectObject("clicked", () => this._toggleMode(), this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
Extension.lookupByUUID(uuid)
|
|
||||||
?.getSettings()
|
|
||||||
.bind(setting, this, "checked", Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
// hacky shit, index to get base object property and set it
|
|
||||||
const checked = this.dbus.proxy[this.prop_name];
|
|
||||||
if (this.checked !== checked) this.dbus.proxy[this.prop_name] = this.checked;
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const checked = this.dbus.proxy[this.prop_name];
|
|
||||||
if (this.checked !== checked) this.set({ checked });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
|
||||||
import { addQuickSettingsItems } from "./helpers";
|
|
||||||
import { quickSettings } from "@girs/gnome-shell/ui";
|
|
||||||
import { Gio } from "@girs/gio-2.0";
|
|
||||||
import { GObject } from "@girs/gobject-2.0";
|
|
||||||
import { uuid } from "../extension";
|
|
||||||
import { DbusBase } from "./dbus_proxy";
|
|
||||||
|
|
||||||
export const AsusSlider = GObject.registerClass(
|
|
||||||
class AsusSlider extends quickSettings.QuickSlider {
|
|
||||||
private dbus: DbusBase;
|
|
||||||
private settings: any = undefined;
|
|
||||||
private setting = "";
|
|
||||||
private prop_name = "";
|
|
||||||
|
|
||||||
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
|
||||||
super({
|
|
||||||
label: title,
|
|
||||||
icon_name: "selection-mode-symbolic",
|
|
||||||
});
|
|
||||||
this.label = title;
|
|
||||||
this.dbus = dbus;
|
|
||||||
this.setting = setting;
|
|
||||||
this.prop_name = prop_name;
|
|
||||||
this.settings = Extension.lookupByUUID(uuid)?.getSettings();
|
|
||||||
|
|
||||||
this._sliderChangedId = this.slider.connect("drag-end", this._onSliderChanged.bind(this));
|
|
||||||
|
|
||||||
// Binding the slider to a GSettings key
|
|
||||||
|
|
||||||
this.settings.connect(`changed::${this.setting}`, this._onSettingsChanged.bind(this));
|
|
||||||
|
|
||||||
// Set an accessible name for the slider
|
|
||||||
this.slider.accessible_name = title;
|
|
||||||
|
|
||||||
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
|
||||||
const properties = changed.deepUnpack();
|
|
||||||
// .find() fails on some shit for some reason
|
|
||||||
for (const v of Object.entries(properties)) {
|
|
||||||
if (v[0] == this.prop_name) {
|
|
||||||
const checked = v[1].unpack();
|
|
||||||
this._sync();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._sync();
|
|
||||||
this._onSettingsChanged();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this], 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSettingsChanged() {
|
|
||||||
// Prevent the slider from emitting a change signal while being updated
|
|
||||||
this.slider.block_signal_handler(this._sliderChangedId);
|
|
||||||
this.slider.value = this.settings.get_uint(this.setting) / 100.0;
|
|
||||||
this.slider.unblock_signal_handler(this._sliderChangedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSliderChanged() {
|
|
||||||
// Assuming our GSettings holds values between 0..100, adjust for the
|
|
||||||
// slider taking values between 0..1
|
|
||||||
const percent = Math.floor(this.slider.value * 100);
|
|
||||||
const stored = Math.floor(this.settings.get_uint(this.setting) / 100.0);
|
|
||||||
if (this.slider.value !== stored) this.dbus.proxy[this.prop_name] = percent;
|
|
||||||
this.settings.set_uint(this.setting, percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
_sync() {
|
|
||||||
const value = this.dbus.proxy[this.prop_name];
|
|
||||||
if (this.slider.value !== value / 100) this.settings.set_uint(this.setting, value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
// "extends": "@tsconfig/strictest/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["ESNext"],
|
|
||||||
"types": [],
|
|
||||||
"target": "ESNext",
|
|
||||||
"module": "ESNext",
|
|
||||||
"moduleResolution": "Bundler",
|
|
||||||
"declaration": true,
|
|
||||||
"removeComments": true,
|
|
||||||
"strict": true,
|
|
||||||
"allowJs": true,
|
|
||||||
"paths": {},
|
|
||||||
"skipLibCheck": true
|
|
||||||
},
|
|
||||||
"files": ["./src/extension.ts"],
|
|
||||||
"include": ["src/*.ts"],
|
|
||||||
"exclude": [".ts-for-girrc.js", ".eslintrc.cjs"]
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,12 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
<!--
|
|
||||||
window.setTimeout('window.location="room4doom/index.html"; ', 0);
|
|
||||||
// -->
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB |
@@ -9,7 +9,7 @@ use crate::AnimeType;
|
|||||||
|
|
||||||
/// Mostly intended to be used with ASUS gifs, but can be used for other
|
/// Mostly intended to be used with ASUS gifs, but can be used for other
|
||||||
/// purposes (like images)
|
/// purposes (like images)
|
||||||
#[derive(Debug, Clone)]
|
#[allow(dead_code)]
|
||||||
pub struct AnimeDiagonal(AnimeType, Vec<Vec<u8>>, Option<Duration>);
|
pub struct AnimeDiagonal(AnimeType, Vec<Vec<u8>>, Option<Duration>);
|
||||||
|
|
||||||
impl AnimeDiagonal {
|
impl AnimeDiagonal {
|
||||||
|
|||||||
+77
-1
@@ -58,13 +58,25 @@ impl From<u8> for Brightness {
|
|||||||
fn from(v: u8) -> Brightness {
|
fn from(v: u8) -> Brightness {
|
||||||
match v {
|
match v {
|
||||||
0 => Brightness::Off,
|
0 => Brightness::Off,
|
||||||
2 => Brightness::Low,
|
1 => Brightness::Low,
|
||||||
3 => Brightness::High,
|
3 => Brightness::High,
|
||||||
_ => Brightness::Med,
|
_ => Brightness::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for Brightness {
|
||||||
|
fn from(v: i32) -> Brightness {
|
||||||
|
(v as u8).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Brightness> for i32 {
|
||||||
|
fn from(v: Brightness) -> i32 {
|
||||||
|
v as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
derive(Type, Value, OwnedValue),
|
derive(Type, Value, OwnedValue),
|
||||||
@@ -90,6 +102,22 @@ impl FromStr for AnimBooting {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AnimBooting {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::GlitchConstruction,
|
||||||
|
1 => Self::StaticEmergence,
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimBooting> for i32 {
|
||||||
|
fn from(value: AnimBooting) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
derive(Type, Value, OwnedValue),
|
derive(Type, Value, OwnedValue),
|
||||||
@@ -115,6 +143,22 @@ impl FromStr for AnimAwake {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AnimAwake {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::BinaryBannerScroll,
|
||||||
|
1 => Self::RogLogoGlitch,
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimAwake> for i32 {
|
||||||
|
fn from(value: AnimAwake) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
derive(Type, Value, OwnedValue),
|
derive(Type, Value, OwnedValue),
|
||||||
@@ -140,6 +184,22 @@ impl FromStr for AnimSleeping {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AnimSleeping {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::BannerSwipe,
|
||||||
|
1 => Self::Starfield,
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimSleeping> for i32 {
|
||||||
|
fn from(value: AnimSleeping) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
derive(Type, Value, OwnedValue),
|
derive(Type, Value, OwnedValue),
|
||||||
@@ -165,6 +225,22 @@ impl FromStr for AnimShutdown {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AnimShutdown {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::GlitchOut,
|
||||||
|
1 => Self::SeeYa,
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimShutdown> for i32 {
|
||||||
|
fn from(value: AnimShutdown) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `get_anime_type` is very broad, matching on part of the laptop board name
|
/// `get_anime_type` is very broad, matching on part of the laptop board name
|
||||||
/// only. For this reason `find_node()` must be used also to verify if the USB
|
/// only. For this reason `find_node()` must be used also to verify if the USB
|
||||||
/// device is available.
|
/// device is available.
|
||||||
|
|||||||
+288
-102
@@ -1,6 +1,7 @@
|
|||||||
([
|
([
|
||||||
(
|
(
|
||||||
board_name: "FA506I",
|
device_name: "FA506I",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -8,7 +9,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FA506Q",
|
device_name: "FA506Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -16,7 +18,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FA507",
|
device_name: "FA507",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa507",
|
layout_name: "fa507",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -24,7 +27,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX505D",
|
device_name: "FX505D",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fx505d",
|
layout_name: "fx505d",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -32,7 +36,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX505G",
|
device_name: "FX505G",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fx505d",
|
layout_name: "fx505d",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -40,7 +45,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX506H",
|
device_name: "FX506H",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -48,7 +54,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX506L",
|
device_name: "FX506L",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -56,7 +63,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX507Z",
|
device_name: "FX507Z",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -64,7 +72,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "FX516P",
|
device_name: "FX516P",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Strobe],
|
basic_modes: [Static, Breathe, Strobe],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -72,7 +81,17 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G512",
|
device_name: "FX705D",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "fx505d",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "G512",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g512",
|
layout_name: "g512",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -80,7 +99,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G512LV",
|
device_name: "G512LV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -88,7 +108,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513I",
|
device_name: "G513I",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -96,7 +117,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513QE",
|
device_name: "G513QE",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -104,7 +126,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513QM",
|
device_name: "G513QM",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -112,7 +135,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513QR",
|
device_name: "G513QR",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -120,7 +144,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513QY",
|
device_name: "G513QY",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -128,7 +153,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513RC",
|
device_name: "G513RC",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -136,7 +162,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513RM",
|
device_name: "G513RM",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -144,7 +171,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G513RW",
|
device_name: "G513RW",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -152,7 +180,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531",
|
device_name: "G531",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -160,7 +189,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531",
|
device_name: "G531",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -168,7 +198,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531GD",
|
device_name: "G531GD",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -176,7 +207,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531GT",
|
device_name: "G531GT",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -184,7 +216,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531GU",
|
device_name: "G531GU",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -192,7 +225,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531GV",
|
device_name: "G531GV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -200,7 +234,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G531GW",
|
device_name: "G531GW",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -208,7 +243,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G532",
|
device_name: "G532",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -216,7 +252,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G533Q",
|
device_name: "G533Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q-per-key",
|
layout_name: "g533q-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -224,7 +261,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G533Z",
|
device_name: "G533Z",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q-per-key",
|
layout_name: "g533q-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -232,7 +270,17 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G634J",
|
device_name: "G614J",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "g634j-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Pulse, Strobe, Rainbow],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard, Lightbar],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "G634J",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g634j-per-key",
|
layout_name: "g634j-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -240,7 +288,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G712LI",
|
device_name: "G712LI",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -248,7 +297,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G712LV",
|
device_name: "G712LV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -256,7 +306,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G712LW",
|
device_name: "G712LW",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -264,7 +315,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713IC",
|
device_name: "G713IC",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -272,7 +324,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713QM",
|
device_name: "G713QM",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -280,7 +333,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713QR",
|
device_name: "G713QR",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -288,7 +342,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713RC",
|
device_name: "G713RC",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -296,7 +351,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713RM",
|
device_name: "G713RM",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -304,7 +360,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713RS",
|
device_name: "G713RS",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -312,7 +369,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G713RW",
|
device_name: "G713RW",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -320,7 +378,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G731",
|
device_name: "G731",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -328,7 +387,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G731GT",
|
device_name: "G731GT",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -336,7 +396,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G731GU",
|
device_name: "G731GU",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -344,7 +405,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G731GV",
|
device_name: "G731GV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -352,7 +414,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G731GW",
|
device_name: "G731GW",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -360,7 +423,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G733C",
|
device_name: "G733C",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [Logo, BarLeft, BarRight],
|
basic_zones: [Logo, BarLeft, BarRight],
|
||||||
@@ -368,7 +432,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G733PZ",
|
device_name: "G733PZ",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g733pz-per-key",
|
layout_name: "g733pz-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -376,7 +441,8 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G733Q",
|
device_name: "G733Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -384,7 +450,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G733Z",
|
device_name: "G733Z",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g513i-per-key",
|
layout_name: "g513i-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -392,7 +459,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "G814JI",
|
device_name: "G814JI",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g814ji-per-key",
|
layout_name: "g814ji-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -400,7 +468,26 @@
|
|||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA401Q",
|
device_name: "G814JZ",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "g814ji-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
power_zones: [Keyboard, Lightbar],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "G834JZ",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "g814ji-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GA401Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -408,23 +495,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA402R",
|
device_name: "GA402N",
|
||||||
layout_name: "ga401q",
|
product_id: "",
|
||||||
basic_modes: [Static, Breathe, Pulse, Rainbow],
|
|
||||||
basic_zones: [],
|
|
||||||
advanced_type: None,
|
|
||||||
power_zones: [Keyboard],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
board_name: "GA402X",
|
|
||||||
layout_name: "ga401q",
|
|
||||||
basic_modes: [Static, Breathe, Pulse, Rainbow],
|
|
||||||
basic_zones: [],
|
|
||||||
advanced_type: None,
|
|
||||||
power_zones: [Keyboard],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
board_name: "GA503Q",
|
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse, Rainbow, Strobe],
|
basic_modes: [Static, Breathe, Pulse, Rainbow, Strobe],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -432,7 +504,26 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA503QE",
|
device_name: "GA402R",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse, Rainbow],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GA402X",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse, Rainbow],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GA402XV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -440,7 +531,17 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA503R",
|
device_name: "GA403UI",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GA503Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse, Rainbow, Strobe],
|
basic_modes: [Static, Breathe, Pulse, Rainbow, Strobe],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -448,7 +549,26 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL503",
|
device_name: "GA503QE",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GA503R",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse, Rainbow, Strobe],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GL503",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -456,7 +576,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL503V",
|
device_name: "GL503V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -464,7 +585,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL504G",
|
device_name: "GL504G",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
|
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
|
||||||
@@ -472,7 +594,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL531",
|
device_name: "GL531",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g512",
|
layout_name: "g512",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -480,7 +603,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL553VE",
|
device_name: "GL553V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, Strobe],
|
basic_modes: [Static, Breathe, Strobe],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -488,7 +612,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GL703G",
|
device_name: "GL703G",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
basic_modes: [Static, Breathe, Strobe, Rainbow],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -496,7 +621,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GM501G",
|
device_name: "GM501G",
|
||||||
|
product_id: "",
|
||||||
layout_name: "fa507",
|
layout_name: "fa507",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -504,7 +630,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU502",
|
device_name: "GU502",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -512,7 +639,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU502G",
|
device_name: "GU502G",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -520,7 +648,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU502L",
|
device_name: "GU502L",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -528,7 +657,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU502LU",
|
device_name: "GU502LU",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -536,7 +666,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU603H",
|
device_name: "GU603H",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -544,7 +675,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU603VV",
|
device_name: "GU603VV",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -552,7 +684,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU603Z",
|
device_name: "GU603Z",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -560,7 +693,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GU604V",
|
device_name: "GU604V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -568,7 +702,17 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV301Q",
|
device_name: "GU605M",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: Zoned([SingleZone]),
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GV301Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -576,7 +720,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV301V",
|
device_name: "GV301V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -584,7 +729,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV301VIC",
|
device_name: "GV301VIC",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -592,7 +738,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV601R",
|
device_name: "GV601R",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -600,7 +747,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV601V",
|
device_name: "GV601V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -608,7 +756,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV604V",
|
device_name: "GV604V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -616,7 +765,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX502",
|
device_name: "GX502",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -624,7 +774,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX531",
|
device_name: "GX531",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
@@ -632,7 +783,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX550L",
|
device_name: "GX550L",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -640,7 +792,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX551Q",
|
device_name: "GX551Q",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -648,7 +801,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX650P",
|
device_name: "GX650P",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -656,7 +810,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX701",
|
device_name: "GX701",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -664,7 +819,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX703H",
|
device_name: "GX703H",
|
||||||
|
product_id: "",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -672,7 +828,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GZ301V",
|
device_name: "GZ301V",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -680,7 +837,8 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "GZ301VIC",
|
device_name: "GZ301VIC",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
@@ -688,11 +846,39 @@
|
|||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "RC71L",
|
device_name: "GZ301Z",
|
||||||
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
])
|
(
|
||||||
|
device_name: "GZ301Z",
|
||||||
|
product_id: "18c6",
|
||||||
|
layout_name: "",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [None],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "GZ301Z",
|
||||||
|
product_id: "1a30",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "RC71L",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
use crate::advanced::LedCode;
|
|
||||||
|
|
||||||
impl From<LedCode> for &str {
|
|
||||||
fn from(k: LedCode) -> Self {
|
|
||||||
(&k).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&LedCode> for &str {
|
|
||||||
fn from(k: &LedCode) -> Self {
|
|
||||||
#[allow(clippy::match_same_arms)]
|
|
||||||
match k {
|
|
||||||
LedCode::VolUp => "Volume Up",
|
|
||||||
LedCode::VolDown => "Volume Down",
|
|
||||||
LedCode::MicMute => "Mute Mic",
|
|
||||||
LedCode::RogApp => "ROG",
|
|
||||||
LedCode::RogFan => "Fan Control",
|
|
||||||
LedCode::Esc => "Escape",
|
|
||||||
LedCode::F1 => "F1",
|
|
||||||
LedCode::F2 => "F2",
|
|
||||||
LedCode::F3 => "F3",
|
|
||||||
LedCode::F4 => "F4",
|
|
||||||
LedCode::F5 => "F5",
|
|
||||||
LedCode::F6 => "F6",
|
|
||||||
LedCode::F7 => "F7",
|
|
||||||
LedCode::F8 => "F8",
|
|
||||||
LedCode::F9 => "F9",
|
|
||||||
LedCode::F10 => "F10",
|
|
||||||
LedCode::F11 => "F11",
|
|
||||||
LedCode::F12 => "F12",
|
|
||||||
LedCode::Del => "Delete",
|
|
||||||
LedCode::Tilde => "Tilde",
|
|
||||||
LedCode::N1 => "1",
|
|
||||||
LedCode::N2 => "2",
|
|
||||||
LedCode::N3 => "3",
|
|
||||||
LedCode::N4 => "4",
|
|
||||||
LedCode::N5 => "5",
|
|
||||||
LedCode::N6 => "6",
|
|
||||||
LedCode::N7 => "7",
|
|
||||||
LedCode::N8 => "8",
|
|
||||||
LedCode::N9 => "9",
|
|
||||||
LedCode::N0 => "0",
|
|
||||||
LedCode::Hyphen => "-",
|
|
||||||
LedCode::Equals => "=",
|
|
||||||
LedCode::Backspace => "Backspace",
|
|
||||||
LedCode::Backspace3_1 => "Backspace LED 1",
|
|
||||||
LedCode::Backspace3_2 => "Backspace LED 2",
|
|
||||||
LedCode::Backspace3_3 => "Backspace LED 3",
|
|
||||||
LedCode::Home => "Home",
|
|
||||||
LedCode::Tab => "Tab",
|
|
||||||
LedCode::Q => "Q",
|
|
||||||
LedCode::W => "W",
|
|
||||||
LedCode::E => "E",
|
|
||||||
LedCode::R => "R",
|
|
||||||
LedCode::T => "T",
|
|
||||||
LedCode::Y => "Y",
|
|
||||||
LedCode::U => "U",
|
|
||||||
LedCode::I => "I",
|
|
||||||
LedCode::O => "O",
|
|
||||||
LedCode::P => "P",
|
|
||||||
LedCode::LBracket => "[",
|
|
||||||
LedCode::RBracket => "]",
|
|
||||||
LedCode::BackSlash => "\\",
|
|
||||||
LedCode::PgUp => "Page Up",
|
|
||||||
LedCode::Caps => "Caps Lock",
|
|
||||||
LedCode::A => "A",
|
|
||||||
LedCode::S => "S",
|
|
||||||
LedCode::D => "D",
|
|
||||||
LedCode::F => "F",
|
|
||||||
LedCode::G => "G",
|
|
||||||
LedCode::H => "H",
|
|
||||||
LedCode::J => "J",
|
|
||||||
LedCode::K => "K",
|
|
||||||
LedCode::L => "L",
|
|
||||||
LedCode::SemiColon => ";",
|
|
||||||
LedCode::Quote => "'",
|
|
||||||
LedCode::Return => "Return",
|
|
||||||
LedCode::Return3_1 => "Return LED 1",
|
|
||||||
LedCode::Return3_2 => "Return LED 2",
|
|
||||||
LedCode::Return3_3 => "Return LED 3",
|
|
||||||
LedCode::PgDn => "Page Down",
|
|
||||||
LedCode::LShift => "Left Shift",
|
|
||||||
LedCode::LShift3_1 => "Left Shift LED 1",
|
|
||||||
LedCode::LShift3_2 => "Left Shift LED 2",
|
|
||||||
LedCode::LShift3_3 => "Left Shift LED 3",
|
|
||||||
LedCode::Z => "Z",
|
|
||||||
LedCode::X => "X",
|
|
||||||
LedCode::C => "C",
|
|
||||||
LedCode::V => "V",
|
|
||||||
LedCode::B => "B",
|
|
||||||
LedCode::N => "N",
|
|
||||||
LedCode::M => "M",
|
|
||||||
LedCode::Comma => ",",
|
|
||||||
LedCode::Period => ".",
|
|
||||||
LedCode::Star => "*",
|
|
||||||
LedCode::NumPadDel => "Delete",
|
|
||||||
LedCode::NumPadPlus => "+",
|
|
||||||
LedCode::NumPadEnter => "Enter",
|
|
||||||
LedCode::NumPadPause => "Pause",
|
|
||||||
LedCode::NumPadPrtSc => "Print Screen",
|
|
||||||
LedCode::NumPadHome => "Home",
|
|
||||||
LedCode::NumLock => "Num-Lock",
|
|
||||||
LedCode::FwdSlash => "/",
|
|
||||||
LedCode::Rshift => "Right Shift",
|
|
||||||
LedCode::Rshift3_1 => "Right Shift LED 1",
|
|
||||||
LedCode::Rshift3_2 => "Right Shift LED 2",
|
|
||||||
LedCode::Rshift3_3 => "Right Shift LED 3",
|
|
||||||
LedCode::End => "End",
|
|
||||||
LedCode::LCtrl => "Left Control",
|
|
||||||
LedCode::LFn => "Left Fn",
|
|
||||||
LedCode::Meta => "Meta",
|
|
||||||
LedCode::LAlt => "Left Alt",
|
|
||||||
LedCode::Spacebar => "Space",
|
|
||||||
LedCode::Spacebar5_1 => "Space LED 1",
|
|
||||||
LedCode::Spacebar5_2 => "Space LED 2",
|
|
||||||
LedCode::Spacebar5_3 => "Space LED 3",
|
|
||||||
LedCode::Spacebar5_4 => "Space LED 4",
|
|
||||||
LedCode::Spacebar5_5 => "Space LED 5",
|
|
||||||
LedCode::RAlt => "Right Alt",
|
|
||||||
LedCode::PrtSc => "Print Screen",
|
|
||||||
LedCode::RCtrl => "Right Control",
|
|
||||||
LedCode::Pause => "Pause",
|
|
||||||
LedCode::Up => "Up",
|
|
||||||
LedCode::Down => "Down",
|
|
||||||
LedCode::Left => "Left",
|
|
||||||
LedCode::Right => "Right",
|
|
||||||
LedCode::RFn => "Right Fn",
|
|
||||||
LedCode::MediaPlay => "Media Play",
|
|
||||||
LedCode::MediaStop => "Media Stop",
|
|
||||||
LedCode::MediaNext => "Media Next",
|
|
||||||
LedCode::MediaPrev => "Media Previous",
|
|
||||||
LedCode::LidLogo => "Lid Logo",
|
|
||||||
LedCode::LidLeft => "Lid Left",
|
|
||||||
LedCode::LidRight => "Lid Right",
|
|
||||||
LedCode::LightbarRight => "Lightbar Right",
|
|
||||||
LedCode::LightbarRightCorner => "Lightbar Right Corner",
|
|
||||||
LedCode::LightbarRightBottom => "Lightbar Right Bottom",
|
|
||||||
LedCode::LightbarLeftBottom => "Lightbar Left Bottom",
|
|
||||||
LedCode::LightbarLeftCorner => "Lightbar Left Corner",
|
|
||||||
LedCode::LightbarLeft => "Lightbar Left",
|
|
||||||
LedCode::Spacing | LedCode::Blocking => "",
|
|
||||||
LedCode::SingleZone => "Single Zoned Keyboard",
|
|
||||||
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)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +1,102 @@
|
|||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use typeshare::typeshare;
|
|
||||||
use zbus::zvariant::{OwnedValue, Type, Value};
|
|
||||||
|
|
||||||
use crate::usb::AuraDevice;
|
use crate::keyboard::AdvancedAuraType;
|
||||||
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
use crate::{AuraModeNum, AuraZone, PowerZones};
|
||||||
|
|
||||||
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
||||||
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
||||||
pub const ASUS_KEYBOARD_DEVICES: [AuraDevice; 8] = [
|
|
||||||
AuraDevice::Tuf,
|
|
||||||
AuraDevice::X1854,
|
|
||||||
AuraDevice::X1869,
|
|
||||||
AuraDevice::X1866,
|
|
||||||
AuraDevice::X18c6,
|
|
||||||
AuraDevice::X19b6,
|
|
||||||
AuraDevice::X1a30,
|
|
||||||
AuraDevice::X1abe,
|
|
||||||
];
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
|
||||||
pub struct LedSupportFile(Vec<LaptopLedData>);
|
|
||||||
|
|
||||||
/// The powerr zones this laptop supports
|
|
||||||
#[typeshare]
|
|
||||||
#[cfg_attr(
|
|
||||||
feature = "dbus",
|
|
||||||
derive(Type, Value, OwnedValue),
|
|
||||||
zvariant(signature = "s")
|
|
||||||
)]
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Copy, Clone)]
|
|
||||||
pub enum PowerZones {
|
|
||||||
/// The logo on some laptop lids
|
|
||||||
#[default]
|
|
||||||
Logo = 0,
|
|
||||||
/// The full keyboard (not zones)
|
|
||||||
Keyboard = 1,
|
|
||||||
/// The lightbar, typically on the front of the laptop
|
|
||||||
Lightbar = 2,
|
|
||||||
/// The leds that may be placed around the edge of the laptop lid
|
|
||||||
Lid = 3,
|
|
||||||
/// The led strip on the rear of some laptops
|
|
||||||
RearGlow = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct LaptopLedData {
|
pub struct LedSupportData {
|
||||||
/// Found via `cat /sys/class/dmi/id/board_name`, e.g `GU603ZW`.
|
/// This can be many different types of name:
|
||||||
/// The match doesn't have to be the complete model number as it is
|
/// - `/sys/class/dmi/id/board_name` (must use for laptops)
|
||||||
/// typically broken down such:
|
/// - The device name from `lsusb`
|
||||||
|
///
|
||||||
|
/// The laptop board_name is found via `cat /sys/class/dmi/id/board_name`,
|
||||||
|
/// e.g `GU603ZW`. The match doesn't have to be the complete model
|
||||||
|
/// number as it is typically broken down such:
|
||||||
/// - GU = product
|
/// - GU = product
|
||||||
/// - 603 = model/platform
|
/// - 603 = model/platform
|
||||||
/// - Z = variant/year or perhaps dGPU model (such as RTX 3xxx)
|
/// - Z = variant/year or perhaps dGPU model (such as RTX 3xxx)
|
||||||
/// - W = possibly dGPU model (such as RTX 3060Ti)
|
/// - W = possibly dGPU model (such as RTX 3060Ti)
|
||||||
pub board_name: String,
|
///
|
||||||
|
/// If using a device name the match is similar to the above where it can be
|
||||||
|
/// partial, so `ASUSTek Computer, Inc. ROG STRIX Arion` can be `STRIX
|
||||||
|
/// Arion` for short. Case insensitive.
|
||||||
|
pub device_name: String,
|
||||||
|
/// The product ID (usb only)
|
||||||
|
/// Example of using a product ID is:
|
||||||
|
/// ```ignore
|
||||||
|
/// $ lsusb
|
||||||
|
/// $ Bus 003 Device 003: ID 0b05:19b6 ASUSTek Computer, Inc. N-KEY Device
|
||||||
|
/// ```
|
||||||
|
/// here `19b6` is all that is required. Case insensitive.
|
||||||
|
#[serde(default)]
|
||||||
|
pub product_id: String,
|
||||||
|
/// Keyboard or device LED layout, this is the name of the externally
|
||||||
|
/// defined layout file. Optional, can be an empty string
|
||||||
|
#[serde(default)]
|
||||||
pub layout_name: String,
|
pub layout_name: String,
|
||||||
|
/// If empty will default to `Static` mode
|
||||||
pub basic_modes: Vec<AuraModeNum>,
|
pub basic_modes: Vec<AuraModeNum>,
|
||||||
|
/// Available on some laptops. This is where the keyboard may be split in to
|
||||||
|
/// 4 zones and may have a logo and lightbar.
|
||||||
|
///
|
||||||
|
/// Ignored if empty.
|
||||||
|
#[serde(default)]
|
||||||
pub basic_zones: Vec<AuraZone>,
|
pub basic_zones: Vec<AuraZone>,
|
||||||
|
/// `Zoned` or `PerKey`.
|
||||||
|
// TODO: remove and use layouts only
|
||||||
|
#[serde(default)]
|
||||||
pub advanced_type: AdvancedAuraType,
|
pub advanced_type: AdvancedAuraType,
|
||||||
|
/// If empty will default to `Keyboard` power zone
|
||||||
pub power_zones: Vec<PowerZones>,
|
pub power_zones: Vec<PowerZones>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LaptopLedData {
|
impl LedSupportData {
|
||||||
pub fn get_data() -> Self {
|
/// Find the data for the device. This function will check DMI info for
|
||||||
|
/// matches against laptops first, then will proceed with matching the
|
||||||
|
/// `device_name` if there are no DMI matches.
|
||||||
|
pub fn get_data(product_id: &str) -> Self {
|
||||||
let dmi = DMIID::new().unwrap_or_default();
|
let dmi = DMIID::new().unwrap_or_default();
|
||||||
// let prod_family = dmi.product_family().expect("Could not get
|
// let prod_family = dmi.product_family().expect("Could not get
|
||||||
// product_family");
|
// product_family");
|
||||||
|
|
||||||
if let Some(modes) = LedSupportFile::load_from_supoprt_db() {
|
if let Some(data) = LedSupportFile::load_from_supoprt_db() {
|
||||||
if let Some(data) = modes.matcher(&dmi.board_name) {
|
if let Some(data) = data.match_device(&dmi.board_name, product_id) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("Using generic LED control for keyboard brightness only");
|
info!("Using generic LED control for keyboard brightness only");
|
||||||
LaptopLedData::default()
|
LedSupportData::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
pub struct LedSupportFile(Vec<LedSupportData>);
|
||||||
|
|
||||||
impl LedSupportFile {
|
impl LedSupportFile {
|
||||||
pub fn get(&self) -> &[LaptopLedData] {
|
pub fn get(&self) -> &[LedSupportData] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The list is stored in ordered format, so the iterator must be reversed
|
/// The list is stored in ordered format, so the iterator must be reversed
|
||||||
/// to ensure we match to *whole names* first before doing a glob match
|
/// to ensure we match to *whole names* first before doing a glob match
|
||||||
pub fn matcher(self, board_name: &str) -> Option<LaptopLedData> {
|
fn match_device(&self, device_name: &str, product_id: &str) -> Option<LedSupportData> {
|
||||||
for config in self.0.iter().rev() {
|
for config in self.0.iter().rev() {
|
||||||
if board_name.contains(&config.board_name) {
|
if device_name.contains(&config.device_name) {
|
||||||
info!("LedSupport: Matched to {}", config.board_name);
|
info!("Matched to {}", config.device_name);
|
||||||
|
if !config.product_id.is_empty() {
|
||||||
|
info!("Checking product ID");
|
||||||
|
if config.product_id == product_id {
|
||||||
|
info!("Matched to {}", config.product_id);
|
||||||
|
return Some(config.clone());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Some(config.clone());
|
return Some(config.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +141,7 @@ impl LedSupportFile {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.0.sort_by(|a, b| a.board_name.cmp(&b.board_name));
|
data.0.sort_by(|a, b| a.device_name.cmp(&b.device_name));
|
||||||
|
|
||||||
if loaded {
|
if loaded {
|
||||||
return Some(data);
|
return Some(data);
|
||||||
@@ -152,16 +160,17 @@ mod tests {
|
|||||||
|
|
||||||
use ron::ser::PrettyConfig;
|
use ron::ser::PrettyConfig;
|
||||||
|
|
||||||
use super::LaptopLedData;
|
use super::LedSupportData;
|
||||||
use crate::advanced::LedCode;
|
|
||||||
use crate::aura_detection::{LedSupportFile, PowerZones};
|
use crate::aura_detection::{LedSupportFile, PowerZones};
|
||||||
|
use crate::keyboard::{AdvancedAuraType, LedCode};
|
||||||
// use crate::zoned::Zone;
|
// use crate::zoned::Zone;
|
||||||
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
use crate::{AuraModeNum, AuraZone};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_data_parse() {
|
fn check_data_parse() {
|
||||||
let led = LaptopLedData {
|
let led = LedSupportData {
|
||||||
board_name: "Test".to_owned(),
|
device_name: "Test".to_owned(),
|
||||||
|
product_id: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
basic_modes: vec![AuraModeNum::Static],
|
basic_modes: vec![AuraModeNum::Static],
|
||||||
basic_zones: vec![AuraZone::Key1, AuraZone::Logo, AuraZone::BarLeft],
|
basic_zones: vec![AuraZone::Key1, AuraZone::Logo, AuraZone::BarLeft],
|
||||||
@@ -184,7 +193,8 @@ mod tests {
|
|||||||
|
|
||||||
// Ensure the data is sorted
|
// Ensure the data is sorted
|
||||||
let mut tmp_sort = tmp.clone();
|
let mut tmp_sort = tmp.clone();
|
||||||
tmp_sort.0.sort_by(|a, b| a.board_name.cmp(&b.board_name));
|
tmp_sort.0.sort_by(|a, b| a.product_id.cmp(&b.product_id));
|
||||||
|
tmp_sort.0.sort_by(|a, b| a.device_name.cmp(&b.device_name));
|
||||||
if tmp != tmp_sort {
|
if tmp != tmp_sort {
|
||||||
let sorted =
|
let sorted =
|
||||||
ron::ser::to_string_pretty(&tmp_sort, PrettyConfig::new().depth_limit(2)).unwrap();
|
ron::ser::to_string_pretty(&tmp_sort, PrettyConfig::new().depth_limit(2)).unwrap();
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
|
||||||
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
|
||||||
pub const LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
|
||||||
pub const LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
|
||||||
pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@@ -67,6 +61,24 @@ impl From<LedBrightness> for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LedBrightness> for i32 {
|
||||||
|
fn from(l: LedBrightness) -> Self {
|
||||||
|
l as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<i32> for LedBrightness {
|
||||||
|
fn from(l: i32) -> Self {
|
||||||
|
match l {
|
||||||
|
0 => LedBrightness::Off,
|
||||||
|
1 => LedBrightness::Low,
|
||||||
|
2 => LedBrightness::Med,
|
||||||
|
3 => LedBrightness::High,
|
||||||
|
_ => LedBrightness::Med,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Copy, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Copy, Deserialize, Serialize)]
|
||||||
@@ -156,6 +168,26 @@ impl FromStr for Speed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for Speed {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::Low,
|
||||||
|
2 => Self::High,
|
||||||
|
_ => Self::Med,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Speed> for i32 {
|
||||||
|
fn from(value: Speed) -> Self {
|
||||||
|
match value {
|
||||||
|
Speed::Low => 0,
|
||||||
|
Speed::Med => 1,
|
||||||
|
Speed::High => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Speed> for u8 {
|
impl From<Speed> for u8 {
|
||||||
fn from(s: Speed) -> u8 {
|
fn from(s: Speed) -> u8 {
|
||||||
match s {
|
match s {
|
||||||
@@ -198,6 +230,23 @@ impl FromStr for Direction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for Direction {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
1 => Self::Left,
|
||||||
|
2 => Self::Up,
|
||||||
|
3 => Self::Down,
|
||||||
|
_ => Self::Right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Direction> for i32 {
|
||||||
|
fn from(value: Direction) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Enum of modes that convert to the actual number required by a USB HID packet
|
/// Enum of modes that convert to the actual number required by a USB HID packet
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -292,6 +341,18 @@ impl From<u8> for AuraModeNum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AuraModeNum {
|
||||||
|
fn from(mode: i32) -> Self {
|
||||||
|
(mode as u8).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AuraModeNum> for i32 {
|
||||||
|
fn from(value: AuraModeNum) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AuraEffect> for AuraModeNum {
|
impl From<AuraEffect> for AuraModeNum {
|
||||||
fn from(value: AuraEffect) -> Self {
|
fn from(value: AuraEffect) -> Self {
|
||||||
value.mode
|
value.mode
|
||||||
@@ -303,7 +364,7 @@ impl From<AuraEffect> for AuraModeNum {
|
|||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
derive(Type, Value, OwnedValue),
|
derive(Type, Value, OwnedValue),
|
||||||
zvariant(signature = "s")
|
zvariant(signature = "u")
|
||||||
)]
|
)]
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub enum AuraZone {
|
pub enum AuraZone {
|
||||||
@@ -345,6 +406,27 @@ impl FromStr for AuraZone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for AuraZone {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
match value {
|
||||||
|
1 => Self::Key1,
|
||||||
|
2 => Self::Key2,
|
||||||
|
3 => Self::Key3,
|
||||||
|
4 => Self::Key4,
|
||||||
|
5 => Self::Logo,
|
||||||
|
6 => Self::BarLeft,
|
||||||
|
7 => Self::BarRight,
|
||||||
|
_ => Self::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AuraZone> for i32 {
|
||||||
|
fn from(value: AuraZone) -> Self {
|
||||||
|
value as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Default factory modes structure. This easily converts to an USB HID packet
|
/// Default factory modes structure. This easily converts to an USB HID packet
|
||||||
/// with:
|
/// with:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
//! Older code that is not useful but stillr elevant as a reference
|
|
||||||
|
|
||||||
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
|
||||||
///
|
|
||||||
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
|
||||||
/// |--------|---------|---------|---------|----------|
|
|
||||||
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
|
||||||
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
|
||||||
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
|
|
||||||
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
|
||||||
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
|
||||||
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
|
||||||
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
|
||||||
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
|
||||||
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
|
||||||
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
|
||||||
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
|
||||||
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
|
||||||
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
|
||||||
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
|
||||||
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
|
||||||
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
|
||||||
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
|
||||||
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
|
|
||||||
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
|
||||||
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
||||||
#[repr(u32)]
|
|
||||||
pub enum AuraDevRog2 {
|
|
||||||
BootLogo = 1,
|
|
||||||
BootKeyb = 1 << 1,
|
|
||||||
AwakeLogo = 1 << 2,
|
|
||||||
AwakeKeyb = 1 << 3,
|
|
||||||
SleepLogo = 1 << 4,
|
|
||||||
SleepKeyb = 1 << 5,
|
|
||||||
ShutdownLogo = 1 << 6,
|
|
||||||
ShutdownKeyb = 1 << 7,
|
|
||||||
BootBar = 1 << (7 + 2),
|
|
||||||
AwakeBar = 1 << (7 + 3),
|
|
||||||
SleepBar = 1 << (7 + 4),
|
|
||||||
ShutdownBar = 1 << (7 + 5),
|
|
||||||
BootLid = 1 << (15 + 1),
|
|
||||||
AwakeLid = 1 << (15 + 2),
|
|
||||||
SleepLid = 1 << (15 + 3),
|
|
||||||
ShutdownLid = 1 << (15 + 4),
|
|
||||||
BootRearGlow = 1 << (23 + 1),
|
|
||||||
AwakeRearGlow = 1 << (23 + 2),
|
|
||||||
SleepRearGlow = 1 << (23 + 3),
|
|
||||||
ShutdownRearGlow = 1 << (23 + 4),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<AuraDevRog2> for u32 {
|
|
||||||
fn from(a: AuraDevRog2) -> Self {
|
|
||||||
a as u32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuraDevRog2 {
|
|
||||||
pub fn to_bytes(control: &[Self]) -> [u8; 4] {
|
|
||||||
let mut a: u32 = 0;
|
|
||||||
for n in control {
|
|
||||||
a |= *n as u32;
|
|
||||||
}
|
|
||||||
[
|
|
||||||
(a & 0xff) as u8,
|
|
||||||
((a & 0xff00) >> 8) as u8,
|
|
||||||
((a & 0xff0000) >> 16) as u8,
|
|
||||||
((a & 0xff000000) >> 24) as u8,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn dev_id() -> &'static str {
|
|
||||||
"0x196b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::deprecated::AuraDevRog2;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_0x19b6_control_bytes_binary_rep() {
|
|
||||||
fn to_binary_string(bytes: &[AuraDevRog2]) -> String {
|
|
||||||
let bytes = AuraDevRog2::to_bytes(bytes);
|
|
||||||
format!(
|
|
||||||
"{:08b}, {:08b}, {:08b}, {:08b}",
|
|
||||||
bytes[0], bytes[1], bytes[2], bytes[3]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let boot_logo_ = to_binary_string(&[AuraDevRog2::BootLogo]);
|
|
||||||
let boot_keyb_ = to_binary_string(&[AuraDevRog2::BootKeyb]);
|
|
||||||
let sleep_logo = to_binary_string(&[AuraDevRog2::SleepLogo]);
|
|
||||||
let sleep_keyb = to_binary_string(&[AuraDevRog2::SleepKeyb]);
|
|
||||||
let awake_logo = to_binary_string(&[AuraDevRog2::AwakeLogo]);
|
|
||||||
let awake_keyb = to_binary_string(&[AuraDevRog2::AwakeKeyb]);
|
|
||||||
let shut_logo_ = to_binary_string(&[AuraDevRog2::ShutdownLogo]);
|
|
||||||
let shut_keyb_ = to_binary_string(&[AuraDevRog2::ShutdownKeyb]);
|
|
||||||
let boot_bar__ = to_binary_string(&[AuraDevRog2::BootBar]);
|
|
||||||
let awake_bar_ = to_binary_string(&[AuraDevRog2::AwakeBar]);
|
|
||||||
let sleep_bar_ = to_binary_string(&[AuraDevRog2::SleepBar]);
|
|
||||||
let shut_bar__ = to_binary_string(&[AuraDevRog2::ShutdownBar]);
|
|
||||||
let boot_lid__ = to_binary_string(&[AuraDevRog2::BootLid]);
|
|
||||||
let awkae_lid_ = to_binary_string(&[AuraDevRog2::AwakeLid]);
|
|
||||||
let sleep_lid_ = to_binary_string(&[AuraDevRog2::SleepLid]);
|
|
||||||
let shut_lid__ = to_binary_string(&[AuraDevRog2::ShutdownLid]);
|
|
||||||
let boot_rear_ = to_binary_string(&[AuraDevRog2::BootRearGlow]);
|
|
||||||
let awake_rear = to_binary_string(&[AuraDevRog2::AwakeRearGlow]);
|
|
||||||
let sleep_rear = to_binary_string(&[AuraDevRog2::SleepRearGlow]);
|
|
||||||
let shut_rear_ = to_binary_string(&[AuraDevRog2::ShutdownRearGlow]);
|
|
||||||
|
|
||||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
|
|
||||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
|
||||||
//
|
|
||||||
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
|
||||||
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
|
||||||
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
|
||||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
|
||||||
//
|
|
||||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
|
||||||
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
|
|
||||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
|
||||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
|
||||||
//
|
|
||||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
|
||||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
|
||||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
|
||||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
|
||||||
|
|
||||||
// All on
|
|
||||||
let byte1 = [
|
|
||||||
AuraDevRog2::BootLogo,
|
|
||||||
AuraDevRog2::BootKeyb,
|
|
||||||
AuraDevRog2::SleepLogo,
|
|
||||||
AuraDevRog2::SleepKeyb,
|
|
||||||
AuraDevRog2::AwakeLogo,
|
|
||||||
AuraDevRog2::AwakeKeyb,
|
|
||||||
AuraDevRog2::ShutdownLogo,
|
|
||||||
AuraDevRog2::ShutdownKeyb,
|
|
||||||
AuraDevRog2::BootBar,
|
|
||||||
AuraDevRog2::AwakeBar,
|
|
||||||
AuraDevRog2::SleepBar,
|
|
||||||
AuraDevRog2::ShutdownBar,
|
|
||||||
AuraDevRog2::AwakeLid,
|
|
||||||
AuraDevRog2::BootLid,
|
|
||||||
AuraDevRog2::SleepLid,
|
|
||||||
AuraDevRog2::ShutdownLid,
|
|
||||||
AuraDevRog2::AwakeRearGlow,
|
|
||||||
AuraDevRog2::BootRearGlow,
|
|
||||||
AuraDevRog2::SleepRearGlow,
|
|
||||||
AuraDevRog2::ShutdownRearGlow,
|
|
||||||
];
|
|
||||||
let out = to_binary_string(&byte1);
|
|
||||||
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::{EffectState, InputForEffect};
|
use super::{EffectState, InputForEffect};
|
||||||
use crate::advanced::LedCode;
|
use crate::keyboard::{KeyLayout, LedCode};
|
||||||
use crate::Colour;
|
use crate::Colour;
|
||||||
|
|
||||||
pub struct InputBased {
|
pub struct InputBased {
|
||||||
@@ -14,7 +14,7 @@ pub struct InputBased {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EffectState for InputBased {
|
impl EffectState for InputBased {
|
||||||
fn next_colour_state(&mut self, _layout: &crate::layouts::KeyLayout) {
|
fn next_colour_state(&mut self, _layout: &KeyLayout) {
|
||||||
self.input.next_colour_state();
|
self.input.next_colour_state();
|
||||||
self.colour = self.input.get_colour();
|
self.colour = self.input.get_colour();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::EffectState;
|
use super::EffectState;
|
||||||
use crate::advanced::LedCode;
|
use crate::keyboard::{KeyLayout, LedCode};
|
||||||
use crate::layouts::KeyLayout;
|
|
||||||
use crate::{effect_state_impl, Colour, Speed};
|
use crate::{effect_state_impl, Colour, Speed};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::advanced::LedCode;
|
|
||||||
use crate::effects::{p_random, EffectState};
|
use crate::effects::{p_random, EffectState};
|
||||||
use crate::layouts::KeyLayout;
|
use crate::keyboard::{KeyLayout, LedCode};
|
||||||
use crate::{effect_state_impl, Colour};
|
use crate::{effect_state_impl, Colour};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ pub use breathe::*;
|
|||||||
mod static_;
|
mod static_;
|
||||||
pub use static_::*;
|
pub use static_::*;
|
||||||
|
|
||||||
use crate::advanced::{LedCode, LedUsbPackets, UsbPackets};
|
use crate::keyboard::{KeyLayout, LedCode, LedUsbPackets, UsbPackets};
|
||||||
use crate::layouts::KeyLayout;
|
|
||||||
use crate::Colour;
|
use crate::Colour;
|
||||||
|
|
||||||
// static mut RNDINDEX: usize = 0;
|
// static mut RNDINDEX: usize = 0;
|
||||||
@@ -132,12 +131,12 @@ macro_rules! effect_state_impl {
|
|||||||
self.colour
|
self.colour
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_led(&self) -> $crate::advanced::LedCode {
|
fn get_led(&self) -> $crate::keyboard::LedCode {
|
||||||
self.led.clone()
|
self.led.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the led type
|
/// Change the led type
|
||||||
fn set_led(&mut self, address: $crate::advanced::LedCode) {
|
fn set_led(&mut self, address: $crate::keyboard::LedCode) {
|
||||||
self.led = address;
|
self.led = address;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -148,14 +147,14 @@ macro_rules! effect_impl {
|
|||||||
($($effect:ident),*) => {
|
($($effect:ident),*) => {
|
||||||
impl Effect {
|
impl Effect {
|
||||||
/// Get the type of LED set
|
/// Get the type of LED set
|
||||||
pub fn led(&self) -> $crate::advanced::LedCode {
|
pub fn led(&self) -> $crate::keyboard::LedCode {
|
||||||
match self {
|
match self {
|
||||||
$(Effect::$effect(c) => c.get_led(),)*
|
$(Effect::$effect(c) => c.get_led(),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the led type (can be used to change location of the effect)
|
/// Change the led type (can be used to change location of the effect)
|
||||||
pub fn set_led(&mut self, address: $crate::advanced::LedCode) {
|
pub fn set_led(&mut self, address: $crate::keyboard::LedCode) {
|
||||||
match self {
|
match self {
|
||||||
$(Effect::$effect(c) => c.set_led(address),)*
|
$(Effect::$effect(c) => c.set_led(address),)*
|
||||||
}
|
}
|
||||||
@@ -200,9 +199,8 @@ effect_impl!(Static, Breathe, DoomFlicker, DoomLightFlash);
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::advanced::LedCode;
|
|
||||||
use crate::effects::{AdvancedEffects, Breathe, DoomFlicker, Effect, Static};
|
use crate::effects::{AdvancedEffects, Breathe, DoomFlicker, Effect, Static};
|
||||||
use crate::layouts::KeyLayout;
|
use crate::keyboard::{KeyLayout, LedCode};
|
||||||
use crate::{Colour, Speed};
|
use crate::{Colour, Speed};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::EffectState;
|
use super::EffectState;
|
||||||
use crate::advanced::LedCode;
|
use crate::keyboard::{KeyLayout, LedCode};
|
||||||
use crate::layouts::KeyLayout;
|
|
||||||
use crate::{effect_state_impl, Colour};
|
use crate::{effect_state_impl, Colour};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ use typeshare::typeshare;
|
|||||||
#[cfg(feature = "dbus")]
|
#[cfg(feature = "dbus")]
|
||||||
use zbus::zvariant::Type;
|
use zbus::zvariant::Type;
|
||||||
|
|
||||||
|
// TODO: GZ301Z
|
||||||
|
// 5dbcd0010300000a00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
|
||||||
|
|
||||||
/// The `LedCode` used in setting up keyboard layouts is important because it
|
/// The `LedCode` used in setting up keyboard layouts is important because it
|
||||||
/// determines the idexing for an RGB value in the final USB packets (for
|
/// determines the idexing for an RGB value in the final USB packets (for
|
||||||
/// per-key addressable keyboards).
|
/// per-key addressable keyboards).
|
||||||
@@ -490,9 +493,157 @@ impl From<LedUsbPackets> for UsbPackets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LedCode> for &str {
|
||||||
|
fn from(k: LedCode) -> Self {
|
||||||
|
(&k).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&LedCode> for &str {
|
||||||
|
fn from(k: &LedCode) -> Self {
|
||||||
|
#[allow(clippy::match_same_arms)]
|
||||||
|
match k {
|
||||||
|
LedCode::VolUp => "Volume Up",
|
||||||
|
LedCode::VolDown => "Volume Down",
|
||||||
|
LedCode::MicMute => "Mute Mic",
|
||||||
|
LedCode::RogApp => "ROG",
|
||||||
|
LedCode::RogFan => "Fan Control",
|
||||||
|
LedCode::Esc => "Escape",
|
||||||
|
LedCode::F1 => "F1",
|
||||||
|
LedCode::F2 => "F2",
|
||||||
|
LedCode::F3 => "F3",
|
||||||
|
LedCode::F4 => "F4",
|
||||||
|
LedCode::F5 => "F5",
|
||||||
|
LedCode::F6 => "F6",
|
||||||
|
LedCode::F7 => "F7",
|
||||||
|
LedCode::F8 => "F8",
|
||||||
|
LedCode::F9 => "F9",
|
||||||
|
LedCode::F10 => "F10",
|
||||||
|
LedCode::F11 => "F11",
|
||||||
|
LedCode::F12 => "F12",
|
||||||
|
LedCode::Del => "Delete",
|
||||||
|
LedCode::Tilde => "Tilde",
|
||||||
|
LedCode::N1 => "1",
|
||||||
|
LedCode::N2 => "2",
|
||||||
|
LedCode::N3 => "3",
|
||||||
|
LedCode::N4 => "4",
|
||||||
|
LedCode::N5 => "5",
|
||||||
|
LedCode::N6 => "6",
|
||||||
|
LedCode::N7 => "7",
|
||||||
|
LedCode::N8 => "8",
|
||||||
|
LedCode::N9 => "9",
|
||||||
|
LedCode::N0 => "0",
|
||||||
|
LedCode::Hyphen => "-",
|
||||||
|
LedCode::Equals => "=",
|
||||||
|
LedCode::Backspace => "Backspace",
|
||||||
|
LedCode::Backspace3_1 => "Backspace LED 1",
|
||||||
|
LedCode::Backspace3_2 => "Backspace LED 2",
|
||||||
|
LedCode::Backspace3_3 => "Backspace LED 3",
|
||||||
|
LedCode::Home => "Home",
|
||||||
|
LedCode::Tab => "Tab",
|
||||||
|
LedCode::Q => "Q",
|
||||||
|
LedCode::W => "W",
|
||||||
|
LedCode::E => "E",
|
||||||
|
LedCode::R => "R",
|
||||||
|
LedCode::T => "T",
|
||||||
|
LedCode::Y => "Y",
|
||||||
|
LedCode::U => "U",
|
||||||
|
LedCode::I => "I",
|
||||||
|
LedCode::O => "O",
|
||||||
|
LedCode::P => "P",
|
||||||
|
LedCode::LBracket => "[",
|
||||||
|
LedCode::RBracket => "]",
|
||||||
|
LedCode::BackSlash => "\\",
|
||||||
|
LedCode::PgUp => "Page Up",
|
||||||
|
LedCode::Caps => "Caps Lock",
|
||||||
|
LedCode::A => "A",
|
||||||
|
LedCode::S => "S",
|
||||||
|
LedCode::D => "D",
|
||||||
|
LedCode::F => "F",
|
||||||
|
LedCode::G => "G",
|
||||||
|
LedCode::H => "H",
|
||||||
|
LedCode::J => "J",
|
||||||
|
LedCode::K => "K",
|
||||||
|
LedCode::L => "L",
|
||||||
|
LedCode::SemiColon => ";",
|
||||||
|
LedCode::Quote => "'",
|
||||||
|
LedCode::Return => "Return",
|
||||||
|
LedCode::Return3_1 => "Return LED 1",
|
||||||
|
LedCode::Return3_2 => "Return LED 2",
|
||||||
|
LedCode::Return3_3 => "Return LED 3",
|
||||||
|
LedCode::PgDn => "Page Down",
|
||||||
|
LedCode::LShift => "Left Shift",
|
||||||
|
LedCode::LShift3_1 => "Left Shift LED 1",
|
||||||
|
LedCode::LShift3_2 => "Left Shift LED 2",
|
||||||
|
LedCode::LShift3_3 => "Left Shift LED 3",
|
||||||
|
LedCode::Z => "Z",
|
||||||
|
LedCode::X => "X",
|
||||||
|
LedCode::C => "C",
|
||||||
|
LedCode::V => "V",
|
||||||
|
LedCode::B => "B",
|
||||||
|
LedCode::N => "N",
|
||||||
|
LedCode::M => "M",
|
||||||
|
LedCode::Comma => ",",
|
||||||
|
LedCode::Period => ".",
|
||||||
|
LedCode::Star => "*",
|
||||||
|
LedCode::NumPadDel => "Delete",
|
||||||
|
LedCode::NumPadPlus => "+",
|
||||||
|
LedCode::NumPadEnter => "Enter",
|
||||||
|
LedCode::NumPadPause => "Pause",
|
||||||
|
LedCode::NumPadPrtSc => "Print Screen",
|
||||||
|
LedCode::NumPadHome => "Home",
|
||||||
|
LedCode::NumLock => "Num-Lock",
|
||||||
|
LedCode::FwdSlash => "/",
|
||||||
|
LedCode::Rshift => "Right Shift",
|
||||||
|
LedCode::Rshift3_1 => "Right Shift LED 1",
|
||||||
|
LedCode::Rshift3_2 => "Right Shift LED 2",
|
||||||
|
LedCode::Rshift3_3 => "Right Shift LED 3",
|
||||||
|
LedCode::End => "End",
|
||||||
|
LedCode::LCtrl => "Left Control",
|
||||||
|
LedCode::LFn => "Left Fn",
|
||||||
|
LedCode::Meta => "Meta",
|
||||||
|
LedCode::LAlt => "Left Alt",
|
||||||
|
LedCode::Spacebar => "Space",
|
||||||
|
LedCode::Spacebar5_1 => "Space LED 1",
|
||||||
|
LedCode::Spacebar5_2 => "Space LED 2",
|
||||||
|
LedCode::Spacebar5_3 => "Space LED 3",
|
||||||
|
LedCode::Spacebar5_4 => "Space LED 4",
|
||||||
|
LedCode::Spacebar5_5 => "Space LED 5",
|
||||||
|
LedCode::RAlt => "Right Alt",
|
||||||
|
LedCode::PrtSc => "Print Screen",
|
||||||
|
LedCode::RCtrl => "Right Control",
|
||||||
|
LedCode::Pause => "Pause",
|
||||||
|
LedCode::Up => "Up",
|
||||||
|
LedCode::Down => "Down",
|
||||||
|
LedCode::Left => "Left",
|
||||||
|
LedCode::Right => "Right",
|
||||||
|
LedCode::RFn => "Right Fn",
|
||||||
|
LedCode::MediaPlay => "Media Play",
|
||||||
|
LedCode::MediaStop => "Media Stop",
|
||||||
|
LedCode::MediaNext => "Media Next",
|
||||||
|
LedCode::MediaPrev => "Media Previous",
|
||||||
|
LedCode::LidLogo => "Lid Logo",
|
||||||
|
LedCode::LidLeft => "Lid Left",
|
||||||
|
LedCode::LidRight => "Lid Right",
|
||||||
|
LedCode::LightbarRight => "Lightbar Right",
|
||||||
|
LedCode::LightbarRightCorner => "Lightbar Right Corner",
|
||||||
|
LedCode::LightbarRightBottom => "Lightbar Right Bottom",
|
||||||
|
LedCode::LightbarLeftBottom => "Lightbar Left Bottom",
|
||||||
|
LedCode::LightbarLeftCorner => "Lightbar Left Corner",
|
||||||
|
LedCode::LightbarLeft => "Lightbar Left",
|
||||||
|
LedCode::Spacing | LedCode::Blocking => "",
|
||||||
|
LedCode::SingleZone => "Single Zoned Keyboard",
|
||||||
|
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)",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::advanced::{LedCode, LedUsbPackets, UsbPackets};
|
use crate::keyboard::{LedCode, LedUsbPackets, UsbPackets};
|
||||||
|
|
||||||
macro_rules! colour_check_zoned {
|
macro_rules! colour_check_zoned {
|
||||||
($zone:expr, $pkt_idx_start:expr) => {
|
($zone:expr, $pkt_idx_start:expr) => {
|
||||||
@@ -8,10 +8,10 @@ use std::slice::Iter;
|
|||||||
use log::warn;
|
use log::warn;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::advanced::LedCode;
|
use crate::aura_detection::LedSupportData;
|
||||||
use crate::aura_detection::LaptopLedData;
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
use crate::keyboard::{AdvancedAuraType, LedCode};
|
||||||
|
use crate::{AuraModeNum, AuraZone};
|
||||||
|
|
||||||
/// The `key_type` plays a role in effects (eventually). You could for example
|
/// The `key_type` plays a role in effects (eventually). You could for example
|
||||||
/// add a `ShapeType::Spacing` to pad out an effect, such as a laserbeam across
|
/// add a `ShapeType::Spacing` to pad out an effect, such as a laserbeam across
|
||||||
@@ -189,7 +189,7 @@ pub struct KeyLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyLayout {
|
impl KeyLayout {
|
||||||
pub fn from_file(path: &Path) -> Result<Self, Error> {
|
fn from_file(path: &Path) -> Result<Self, Error> {
|
||||||
let buf: String = std::fs::read_to_string(path)
|
let buf: String = std::fs::read_to_string(path)
|
||||||
.map_err(|e| Error::IoPath(path.to_string_lossy().to_string(), e))?;
|
.map_err(|e| Error::IoPath(path.to_string_lossy().to_string(), e))?;
|
||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
@@ -278,7 +278,7 @@ impl KeyLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
||||||
pub fn find_layout(led_data: LaptopLedData, mut data_path: PathBuf) -> Result<Self, Error> {
|
pub fn find_layout(led_data: LedSupportData, mut data_path: PathBuf) -> Result<Self, Error> {
|
||||||
// TODO: locales
|
// TODO: locales
|
||||||
let layout_name = if led_data.layout_name.is_empty() {
|
let layout_name = if led_data.layout_name.is_empty() {
|
||||||
"ga401q".to_owned() // Need some sort of default here due to ROGCC
|
"ga401q".to_owned() // Need some sort of default here due to ROGCC
|
||||||
@@ -459,7 +459,7 @@ mod tests {
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::aura_detection::LedSupportFile;
|
use crate::aura_detection::LedSupportFile;
|
||||||
use crate::layouts::KeyLayout;
|
use crate::keyboard::KeyLayout;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_parse_all() {
|
fn check_parse_all() {
|
||||||
@@ -531,6 +531,10 @@ mod tests {
|
|||||||
data_path.push("loop_prep");
|
data_path.push("loop_prep");
|
||||||
|
|
||||||
for config in data.get().iter().rev() {
|
for config in data.get().iter().rev() {
|
||||||
|
if config.layout_name.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
let layout_file = format!("{}_US.ron", config.layout_name);
|
let layout_file = format!("{}_US.ron", config.layout_name);
|
||||||
@@ -543,7 +547,7 @@ mod tests {
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
"Error checking {data_path:?} for {} : {e:?}",
|
"Error checking {data_path:?} for {} : {e:?}",
|
||||||
config.board_name
|
config.device_name
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -551,7 +555,7 @@ mod tests {
|
|||||||
if let Err(e) = file.read_to_string(&mut buf) {
|
if let Err(e) = file.read_to_string(&mut buf) {
|
||||||
panic!(
|
panic!(
|
||||||
"Error checking {data_path:?} for {} : {e:?}",
|
"Error checking {data_path:?} for {} : {e:?}",
|
||||||
config.board_name
|
config.device_name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if let Err(e) = ron::from_str::<KeyLayout>(&buf) {
|
if let Err(e) = ron::from_str::<KeyLayout>(&buf) {
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/// All handling for `RgbAddress`ing.
|
||||||
|
mod advanced;
|
||||||
|
pub use advanced::*;
|
||||||
|
|
||||||
|
/// Helpers for consructing keyboard layouts for UI use and effects
|
||||||
|
mod layouts;
|
||||||
|
pub use layouts::*;
|
||||||
|
|
||||||
|
mod power;
|
||||||
|
pub use power::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub enum AdvancedAuraType {
|
||||||
|
/// A `None` will apply the effect to the whole keyboard via basic-static
|
||||||
|
/// mode
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Zoned(Vec<LedCode>),
|
||||||
|
PerKey,
|
||||||
|
}
|
||||||
@@ -0,0 +1,583 @@
|
|||||||
|
//! Power state for Laptop MCU RGB/LED. This is generally for newer
|
||||||
|
//! 0x18c6, 0x19B6, 0x1a30, keyboard models (2021+)
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::ops::{BitAnd, BitOr};
|
||||||
|
|
||||||
|
use log::warn;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use typeshare::typeshare;
|
||||||
|
#[cfg(feature = "dbus")]
|
||||||
|
use zbus::zvariant::{OwnedValue, Type, Value};
|
||||||
|
|
||||||
|
use crate::aura_detection::LedSupportData;
|
||||||
|
use crate::{AuraDeviceType, PowerZones};
|
||||||
|
|
||||||
|
/// Meaning of this struct depends on the laptop generation.
|
||||||
|
/// - 2021+, the struct is a single zone with 4 states
|
||||||
|
/// - pre-2021, the struct is 1 or 2 zones and 3 states
|
||||||
|
/// - Tuf, the struct is 1 zone and 3 states
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct AuraPowerState {
|
||||||
|
pub zone: PowerZones,
|
||||||
|
pub boot: bool,
|
||||||
|
pub awake: bool,
|
||||||
|
pub sleep: bool,
|
||||||
|
/// Ignored for pre-2021 and Tuf
|
||||||
|
pub shutdown: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AuraPowerState {
|
||||||
|
/// Defaults all to off
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
boot: true,
|
||||||
|
awake: true,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuraPowerState {
|
||||||
|
fn default_for(zone: PowerZones) -> Self {
|
||||||
|
Self {
|
||||||
|
zone,
|
||||||
|
boot: true,
|
||||||
|
awake: true,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tuf_to_bytes(&self) -> Vec<u8> {
|
||||||
|
todo!("0s and 1s for bool array")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Bits for older 0x1866 keyboard model
|
||||||
|
///
|
||||||
|
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
||||||
|
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
|
||||||
|
/// enabled)
|
||||||
|
///
|
||||||
|
/// | Byte 1 | Byte 2 | Byte 3 | function | hex |
|
||||||
|
/// |------------|------------|------------|----------|----------|
|
||||||
|
/// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
|
||||||
|
/// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
|
||||||
|
/// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
|
||||||
|
/// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
|
||||||
|
/// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
|
||||||
|
/// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
|
||||||
|
fn old_to_bytes(&self) -> Vec<u8> {
|
||||||
|
let mut a: u32 = 0;
|
||||||
|
if self.awake {
|
||||||
|
a |= OldAuraPower::Awake as u32;
|
||||||
|
}
|
||||||
|
if self.boot {
|
||||||
|
a |= OldAuraPower::Boot as u32;
|
||||||
|
}
|
||||||
|
if self.sleep {
|
||||||
|
a |= OldAuraPower::Sleep as u32;
|
||||||
|
}
|
||||||
|
if matches!(
|
||||||
|
self.zone,
|
||||||
|
PowerZones::Keyboard | PowerZones::KeyboardAndLightbar
|
||||||
|
) {
|
||||||
|
a |= OldAuraPower::Keyboard as u32;
|
||||||
|
}
|
||||||
|
if matches!(
|
||||||
|
self.zone,
|
||||||
|
PowerZones::Lightbar | PowerZones::KeyboardAndLightbar
|
||||||
|
) {
|
||||||
|
a |= OldAuraPower::Lightbar as u32;
|
||||||
|
}
|
||||||
|
vec![
|
||||||
|
((a & 0xff0000) >> 16) as u8,
|
||||||
|
((a & 0xff00) >> 8) as u8,
|
||||||
|
(a & 0xff) as u8,
|
||||||
|
0x00,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_to_byte(&self) -> u32 {
|
||||||
|
match self.zone {
|
||||||
|
PowerZones::Logo => {
|
||||||
|
self.boot as u32
|
||||||
|
| (self.awake as u32) << 2
|
||||||
|
| (self.sleep as u32) << 4
|
||||||
|
| (self.shutdown as u32) << 6
|
||||||
|
}
|
||||||
|
PowerZones::Keyboard => {
|
||||||
|
(self.boot as u32) << 1
|
||||||
|
| (self.awake as u32) << 3
|
||||||
|
| (self.sleep as u32) << 5
|
||||||
|
| (self.shutdown as u32) << 7
|
||||||
|
}
|
||||||
|
PowerZones::Lightbar => {
|
||||||
|
(self.boot as u32) << (7 + 2)
|
||||||
|
| (self.awake as u32) << (7 + 3)
|
||||||
|
| (self.sleep as u32) << (7 + 4)
|
||||||
|
| (self.shutdown as u32) << (7 + 5)
|
||||||
|
}
|
||||||
|
PowerZones::Lid => {
|
||||||
|
(self.boot as u32) << (15 + 1)
|
||||||
|
| (self.awake as u32) << (15 + 2)
|
||||||
|
| (self.sleep as u32) << (15 + 3)
|
||||||
|
| (self.shutdown as u32) << (15 + 4)
|
||||||
|
}
|
||||||
|
PowerZones::RearGlow => {
|
||||||
|
(self.boot as u32) << (23 + 1)
|
||||||
|
| (self.awake as u32) << (23 + 2)
|
||||||
|
| (self.sleep as u32) << (23 + 3)
|
||||||
|
| (self.shutdown as u32) << (23 + 4)
|
||||||
|
}
|
||||||
|
PowerZones::KeyboardAndLightbar | PowerZones::None => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[typeshare]
|
||||||
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct LaptopAuraPower {
|
||||||
|
pub states: Vec<AuraPowerState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LaptopAuraPower {
|
||||||
|
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||||
|
///
|
||||||
|
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||||
|
/// |--------|---------|---------|---------|----------|
|
||||||
|
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||||
|
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||||
|
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||||
|
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||||
|
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||||
|
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||||
|
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||||
|
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||||
|
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||||
|
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||||
|
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||||
|
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||||
|
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||||
|
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||||
|
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||||
|
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||||
|
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||||
|
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||||
|
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||||
|
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||||
|
fn new_to_bytes(&self) -> Vec<u8> {
|
||||||
|
let mut a: u32 = 0;
|
||||||
|
for state in self.states.iter() {
|
||||||
|
a |= state.new_to_byte();
|
||||||
|
}
|
||||||
|
vec![
|
||||||
|
(a & 0xff) as u8,
|
||||||
|
((a & 0xff00) >> 8) as u8,
|
||||||
|
((a & 0xff0000) >> 16) as u8,
|
||||||
|
((a & 0xff000000) >> 24) as u8,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use support data to setup correct zones
|
||||||
|
pub fn new(aura_type: AuraDeviceType, support_data: &LedSupportData) -> Self {
|
||||||
|
match aura_type {
|
||||||
|
AuraDeviceType::Unknown | AuraDeviceType::LaptopPost2021 => {
|
||||||
|
let mut states = Vec::new();
|
||||||
|
for zone in support_data.power_zones.iter() {
|
||||||
|
states.push(AuraPowerState::default_for(*zone))
|
||||||
|
}
|
||||||
|
Self { states }
|
||||||
|
}
|
||||||
|
AuraDeviceType::LaptopPre2021 => {
|
||||||
|
if support_data.power_zones.contains(&PowerZones::Lightbar) {
|
||||||
|
Self {
|
||||||
|
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self {
|
||||||
|
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AuraDeviceType::LaptopTuf => Self {
|
||||||
|
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||||
|
},
|
||||||
|
AuraDeviceType::ScsiExtDisk => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_bytes(&self, aura_type: AuraDeviceType) -> Vec<u8> {
|
||||||
|
match aura_type {
|
||||||
|
AuraDeviceType::LaptopPost2021 => self.new_to_bytes(),
|
||||||
|
AuraDeviceType::LaptopPre2021 => self
|
||||||
|
.states
|
||||||
|
.first()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.old_to_bytes(),
|
||||||
|
AuraDeviceType::LaptopTuf => self
|
||||||
|
.states
|
||||||
|
.first()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.tuf_to_bytes(),
|
||||||
|
AuraDeviceType::Unknown => {
|
||||||
|
warn!("Trying to create bytes for an unknown device");
|
||||||
|
self.new_to_bytes()
|
||||||
|
}
|
||||||
|
AuraDeviceType::ScsiExtDisk => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// | Byte 1 | Byte 2 | Byte 3 | function | hex |
|
||||||
|
/// |------------|------------|------------|----------|----------|
|
||||||
|
/// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
|
||||||
|
/// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
|
||||||
|
/// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
|
||||||
|
/// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
|
||||||
|
/// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
|
||||||
|
/// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
|
||||||
|
#[repr(u32)]
|
||||||
|
enum OldAuraPower {
|
||||||
|
Awake = 0x000002,
|
||||||
|
Boot = 0xc31209,
|
||||||
|
Sleep = 0x300804,
|
||||||
|
Keyboard = 0x080000,
|
||||||
|
Lightbar = 0x040500,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr<OldAuraPower> for OldAuraPower {
|
||||||
|
type Output = u32;
|
||||||
|
|
||||||
|
fn bitor(self, rhs: OldAuraPower) -> Self::Output {
|
||||||
|
self as u32 | rhs as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitAnd<OldAuraPower> for OldAuraPower {
|
||||||
|
type Output = u32;
|
||||||
|
|
||||||
|
fn bitand(self, rhs: OldAuraPower) -> Self::Output {
|
||||||
|
self as u32 & rhs as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OldAuraPower> for u32 {
|
||||||
|
fn from(a: OldAuraPower) -> Self {
|
||||||
|
a as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||||
|
use crate::{AuraDeviceType, PowerZones};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_0x1866_control_bytes() {
|
||||||
|
let state = AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
awake: true,
|
||||||
|
boot: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
};
|
||||||
|
let bytes = state.old_to_bytes();
|
||||||
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
|
assert_eq!(bytes, [0x08, 0x00, 0x02, 0x00]);
|
||||||
|
|
||||||
|
let state = AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
awake: true,
|
||||||
|
boot: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
};
|
||||||
|
let bytes = state.old_to_bytes();
|
||||||
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
|
assert_eq!(bytes, [0x04, 0x05, 0x02, 0x00]);
|
||||||
|
|
||||||
|
let bytes = AuraPowerState {
|
||||||
|
zone: PowerZones::None,
|
||||||
|
awake: false,
|
||||||
|
boot: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
};
|
||||||
|
let bytes = bytes.old_to_bytes();
|
||||||
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
|
assert_eq!(bytes, [0x30, 0x08, 0x04, 0x00]);
|
||||||
|
|
||||||
|
let bytes = AuraPowerState {
|
||||||
|
zone: PowerZones::None,
|
||||||
|
awake: false,
|
||||||
|
boot: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
};
|
||||||
|
let bytes = bytes.old_to_bytes();
|
||||||
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
|
assert_eq!(bytes, [0xc3, 0x12, 0x09, 0x00]);
|
||||||
|
|
||||||
|
let power = AuraPowerState {
|
||||||
|
zone: PowerZones::KeyboardAndLightbar,
|
||||||
|
awake: true,
|
||||||
|
boot: true,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let bytes = power.old_to_bytes();
|
||||||
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
|
assert_eq!(bytes, [0xff, 0x1f, 0x000f, 0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_0x19b6_control_bytes_binary_rep() {
|
||||||
|
fn to_binary_string(power: &LaptopAuraPower) -> String {
|
||||||
|
let bytes = power.to_bytes(AuraDeviceType::LaptopPost2021);
|
||||||
|
format!(
|
||||||
|
"{:08b}, {:08b}, {:08b}, {:08b}",
|
||||||
|
bytes[0], bytes[1], bytes[2], bytes[3]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let boot_logo_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Logo,
|
||||||
|
boot: true,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let boot_keyb_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
boot: true,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sleep_logo = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Logo,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sleep_keyb = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let awake_logo = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Logo,
|
||||||
|
boot: false,
|
||||||
|
awake: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let awake_keyb = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
boot: false,
|
||||||
|
awake: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let shut_logo_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Logo,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: true,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let shut_keyb_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: true,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let boot_bar__ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
boot: true,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let awake_bar_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
boot: false,
|
||||||
|
awake: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sleep_bar_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let shut_bar__ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: true,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let boot_lid__ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lid,
|
||||||
|
boot: true,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let awake_lid_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lid,
|
||||||
|
boot: false,
|
||||||
|
awake: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sleep_lid_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lid,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let shut_lid__ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::Lid,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: true,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let boot_rear_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::RearGlow,
|
||||||
|
boot: true,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let awake_rear = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::RearGlow,
|
||||||
|
boot: false,
|
||||||
|
awake: true,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let sleep_rear = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::RearGlow,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: true,
|
||||||
|
shutdown: false,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
let shut_rear_ = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![AuraPowerState {
|
||||||
|
zone: PowerZones::RearGlow,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: true,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
|
||||||
|
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||||
|
//
|
||||||
|
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
||||||
|
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
||||||
|
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||||
|
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||||
|
//
|
||||||
|
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
||||||
|
assert_eq!(awake_lid_, "00000000, 00000000, 00000010, 00000000");
|
||||||
|
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
||||||
|
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
||||||
|
//
|
||||||
|
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
||||||
|
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
||||||
|
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
||||||
|
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
||||||
|
|
||||||
|
// All on
|
||||||
|
let byte1 = to_binary_string(&LaptopAuraPower {
|
||||||
|
states: vec![
|
||||||
|
AuraPowerState {
|
||||||
|
zone: PowerZones::Keyboard,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AuraPowerState {
|
||||||
|
zone: PowerZones::Lid,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AuraPowerState {
|
||||||
|
zone: PowerZones::Logo,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AuraPowerState {
|
||||||
|
zone: PowerZones::Lightbar,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AuraPowerState {
|
||||||
|
zone: PowerZones::RearGlow,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
assert_eq!(byte1, "11111111, 00011110, 00001111, 00001111");
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user