Compare commits

...

30 Commits

Author SHA1 Message Date
Ghoul
f4c69c7e8c Merge branch 'main' into 'devel'
Draft: Add custom image and gif support for G835L

See merge request asus-linux/asusctl!249
2026-01-21 15:00:51 +00:00
Yaseen
7cf6c477eb feat: add G835L diagonal test images 2026-01-21 20:00:15 +05:00
Yaseen
b9c251d403 feat: add anime-led-scan tool
Usage: cargo run --example anime-led-scan
2026-01-21 20:00:03 +05:00
Yaseen
6ef977f6ae chore: fix comments documenting Scar 18 implementation plan
Removed comments mentioning monochrome/grayscale LEDs added under the
impression G14 and M16 used to have RGB LED lighting. This assumption
has been proved false.

Additionally added agent md files to gitignore and uncommented G635L
width as even a random value is likely necessary
2026-01-21 16:27:33 +05:00
Yaseen
d006837198 chore: add implementation planning for G635L/G835L support 2026-01-21 01:12:14 +05:00
Denis Benato
6e83884c0a feat: GUI rework 2026-01-19 02:20:53 +01:00
Denis Benato
7edb77b41f fix: make the linter happy again 2026-01-18 23:43:22 +01:00
Denis Benato
737ffa522c chore: update CHANGELOG.md 2026-01-18 23:41:26 +01:00
Denis Benato
0311cfb1f9 fix: improve handling of different attribute types 2026-01-18 23:38:45 +01:00
Denis Benato
b0ee27fb74 Merge branch 'rogcc_toast_look_update' into 'devel'
rog-control-center toast message update

See merge request asus-linux/asusctl!248
2026-01-18 22:15:02 +00:00
Mykola Shevchenko
d4eca0c93e feat: improve toast message for rogcc 2026-01-18 22:15:02 +00:00
Denis Benato
a9f4aac875 Release: 6.3.1 2026-01-18 15:44:30 +01:00
Denis Benato
8377056580 chore: add Quiet/LowPower entry to CHANGELOG.md 2026-01-18 15:39:50 +01:00
Denis Benato
d541581012 fix: do not write unavailable settings to the config file 2026-01-18 15:38:41 +01:00
Denis Benato
72ef6dea07 chore: update README.md and use rust-toolchain file 2026-01-17 16:46:02 +01:00
Denis Benato
bfadc39400 Merge branch 'g615lr-rgb' into 'devel'
feat: add support for G615LR to aura_support.ron

See merge request asus-linux/asusctl!247
2026-01-17 15:39:43 +00:00
Burak
754d82d031 feat: add support for G615LR to aura_support.ron 2026-01-17 18:09:43 +03:00
Denis Benato
8ae072ea82 chore: update README.md for translation 2026-01-17 15:16:35 +01:00
Denis Benato
cec2168591 Merge branch 'rogcc_ukrainian_translations' into 'devel'
rog-control-center Ukrainian language added

See merge request asus-linux/asusctl!246
2026-01-17 14:08:02 +00:00
Mykola Shevchenko
8d6acc5975 rog-control-center Ukrainian language added 2026-01-17 14:02:04 +02:00
Denis Benato
b20ecf5378 chore: README.md edits 2026-01-16 19:53:58 +01:00
Denis Benato
ade839e981 chore: Update README.md 2026-01-16 19:18:15 +01:00
Denis Benato
d625c279a6 fix: G835LW doesn't have pulse available in windows 2026-01-16 19:13:00 +01:00
Denis Benato
5ea14be3fa chore: add extra/index.html: docs landing redirect to asusctl docs 2026-01-14 14:25:13 +01:00
Denis Benato
64c2e55db4 chore: prepare for a new version 2026-01-14 02:27:39 +01:00
Denis Benato
5303bfc1ad Release: 6.3.0 2026-01-14 02:16:22 +01:00
Denis Benato
635f1dc9b9 Feat: add support for G835L 2026-01-14 02:13:30 +01:00
Denis Benato
33a4dba8fe fix: rogcc not starting in rog ally 2026-01-14 02:10:03 +01:00
Denis Benato
e4680c9543 Merge branch 'remove_supergfxctl' into devel 2026-01-14 02:02:26 +01:00
Denis Benato
e9c5315bda Feat: Remove supergfxctl notification daemon 2026-01-13 22:05:34 +01:00
35 changed files with 2724 additions and 570 deletions

5
.gitignore vendored
View File

@@ -20,3 +20,8 @@ desktop-extensions/gnome*/@types/gir-generated
desktop-extensions/gnome*/node_modules
desktop-extensions/gnome*/schemas/gschemas.compiled
desktop-extensions/gnome*/*.zip
# agents and reference
CLAUDE.md
AGENTS.md
/reference

View File

@@ -90,7 +90,7 @@ pages:
- rm -rf public
- mkdir public
- cp -R ci-target/doc/* public
- cp extra/index.html public
- if [ -f extra/index.html ]; then cp extra/index.html public; else echo "no extra/index.html to copy"; fi
artifacts:
paths:
- public

View File

@@ -1,12 +1,27 @@
# Changelog
## [Unreleased]
## [6.3.2]
### Changes
- Improve the notification area, @shevchenko0013 strikes again!
- Improve firmware attributes handling
## [6.3.1]
### Changes
- Removed a lighting mode that is unavailable in windows to G835L: thanks to @shevchenko0013 again!
- Added translations for Ukranian language, thanks @shevchenko0013!
- Added LEDs definition for G615LR, thanks @btnrv
- Fix improper usage of Quiet when only LowPower is available
## [6.3.0]
### Changed
- Added support for TUF keyboard powerstate control
- Improved AniMe Matrix support thanks to @Seom1177 !
- Fixed a bug with one-shot battery change, thanks @bitr8 !
- Changed the CLI interface of asusctl to be less confusing
- Added support for G835L, thanks to @shevchenko0013 !
## [6.2.0]

133
Cargo.lock generated
View File

@@ -212,7 +212,7 @@ dependencies = [
[[package]]
name = "asusctl"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"argh",
"dmi_id",
@@ -232,7 +232,7 @@ dependencies = [
[[package]]
name = "asusd"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"cargo-husky",
"concat-idents",
@@ -259,7 +259,7 @@ dependencies = [
[[package]]
name = "asusd-user"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"config-traits",
"dirs",
@@ -816,9 +816,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]]
name = "cc"
version = "1.2.52"
version = "1.2.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -864,9 +864,9 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.42"
version = "0.4.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -938,7 +938,7 @@ dependencies = [
[[package]]
name = "config-traits"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"log",
"ron",
@@ -987,7 +987,7 @@ dependencies = [
[[package]]
name = "const-field-offset"
version = "0.1.5"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"const-field-offset-macro",
"field-offset",
@@ -996,7 +996,7 @@ dependencies = [
[[package]]
name = "const-field-offset-macro"
version = "0.1.5"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"proc-macro2",
"quote",
@@ -1274,7 +1274,7 @@ dependencies = [
[[package]]
name = "dmi_id"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"log",
"udev 0.8.0",
@@ -1545,9 +1545,9 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
version = "0.1.7"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
[[package]]
name = "flate2"
@@ -2246,7 +2246,7 @@ dependencies = [
[[package]]
name = "i-slint-backend-linuxkms"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"calloop 0.14.3",
"drm",
@@ -2264,7 +2264,7 @@ dependencies = [
[[package]]
name = "i-slint-backend-selector"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"cfg-if",
"i-slint-backend-linuxkms",
@@ -2277,7 +2277,7 @@ dependencies = [
[[package]]
name = "i-slint-backend-winit"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"block2 0.6.2",
"cfg-if",
@@ -2316,7 +2316,7 @@ dependencies = [
[[package]]
name = "i-slint-common"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"fontique",
"ttf-parser 0.25.1",
@@ -2325,7 +2325,7 @@ dependencies = [
[[package]]
name = "i-slint-compiler"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"annotate-snippets",
"by_address",
@@ -2353,7 +2353,7 @@ dependencies = [
[[package]]
name = "i-slint-core"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"auto_enums",
"bitflags 2.10.0",
@@ -2402,7 +2402,7 @@ dependencies = [
[[package]]
name = "i-slint-core-macros"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"quote",
"serde_json",
@@ -2412,7 +2412,7 @@ dependencies = [
[[package]]
name = "i-slint-renderer-femtovg"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"cfg-if",
"const-field-offset",
@@ -2434,7 +2434,7 @@ dependencies = [
[[package]]
name = "i-slint-renderer-skia"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"bytemuck",
"cfg-if",
@@ -2469,7 +2469,7 @@ dependencies = [
[[package]]
name = "i-slint-renderer-software"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"bytemuck",
"clru",
@@ -2632,8 +2632,8 @@ dependencies = [
"rayon",
"rgb",
"tiff",
"zune-core 0.5.0",
"zune-jpeg 0.5.8",
"zune-core 0.5.1",
"zune-jpeg 0.5.9",
]
[[package]]
@@ -2819,9 +2819,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.83"
version = "0.3.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -4482,7 +4482,7 @@ dependencies = [
[[package]]
name = "rog-control-center"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"asusd",
"concat-idents",
@@ -4513,7 +4513,7 @@ dependencies = [
[[package]]
name = "rog_anime"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"dmi_id",
"gif 0.12.0",
@@ -4527,7 +4527,7 @@ dependencies = [
[[package]]
name = "rog_aura"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"dmi_id",
"log",
@@ -4538,7 +4538,7 @@ dependencies = [
[[package]]
name = "rog_dbus"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"asusd",
"rog_anime",
@@ -4552,7 +4552,7 @@ dependencies = [
[[package]]
name = "rog_platform"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"concat-idents",
"inotify",
@@ -4565,7 +4565,7 @@ dependencies = [
[[package]]
name = "rog_profiles"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"log",
"rog_platform",
@@ -4576,7 +4576,7 @@ dependencies = [
[[package]]
name = "rog_scsi"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"ron",
"serde",
@@ -4586,7 +4586,7 @@ dependencies = [
[[package]]
name = "rog_simulators"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"log",
"rog_anime",
@@ -4596,7 +4596,7 @@ dependencies = [
[[package]]
name = "rog_slash"
version = "6.2.0"
version = "6.3.1"
dependencies = [
"dmi_id",
"serde",
@@ -4975,7 +4975,7 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]]
name = "slint"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"const-field-offset",
"i-slint-backend-selector",
@@ -4995,7 +4995,7 @@ dependencies = [
[[package]]
name = "slint-build"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"derive_more",
"i-slint-compiler",
@@ -5006,7 +5006,7 @@ dependencies = [
[[package]]
name = "slint-macros"
version = "1.15.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"i-slint-compiler",
"proc-macro2",
@@ -5778,9 +5778,9 @@ dependencies = [
[[package]]
name = "typed-index-collections"
version = "3.4.0"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5318ee4ce62a4e948a33915574021a7a953d83e84fba6e25c72ffcfd7dad35ff"
checksum = "898160f1dfd383b4e92e17f0512a7d62f3c51c44937b23b6ffc3a1614a8eaccd"
dependencies = [
"bincode",
"serde",
@@ -6030,7 +6030,7 @@ dependencies = [
[[package]]
name = "vtable"
version = "0.3.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"const-field-offset",
"portable-atomic",
@@ -6041,7 +6041,7 @@ dependencies = [
[[package]]
name = "vtable-macro"
version = "0.3.0"
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
source = "git+https://github.com/slint-ui/slint.git#75fb4125d8082c5c64b4ce8220c6fe607c8caac0"
dependencies = [
"proc-macro2",
"quote",
@@ -6075,18 +6075,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.106"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
dependencies = [
"cfg-if",
"once_cell",
@@ -6097,11 +6097,12 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.56"
version = "0.4.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f"
dependencies = [
"cfg-if",
"futures-util",
"js-sys",
"once_cell",
"wasm-bindgen",
@@ -6110,9 +6111,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.106"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -6120,9 +6121,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.106"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
dependencies = [
"bumpalo",
"proc-macro2",
@@ -6133,9 +6134,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.106"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
dependencies = [
"unicode-ident",
]
@@ -6277,9 +6278,9 @@ dependencies = [
[[package]]
name = "web-sys"
version = "0.3.83"
version = "0.3.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -6980,9 +6981,9 @@ dependencies = [
[[package]]
name = "wit-bindgen"
version = "0.46.0"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "write-fonts"
@@ -7293,9 +7294,9 @@ dependencies = [
[[package]]
name = "zmij"
version = "1.0.14"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea"
checksum = "94f63c051f4fe3c1509da62131a678643c5b6fbdc9273b2b79d4378ebda003d2"
[[package]]
name = "zune-core"
@@ -7305,9 +7306,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-core"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773"
checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"
[[package]]
name = "zune-inflate"
@@ -7329,11 +7330,11 @@ dependencies = [
[[package]]
name = "zune-jpeg"
version = "0.5.8"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e35aee689668bf9bd6f6f3a6c60bb29ba1244b3b43adfd50edd554a371da37d5"
checksum = "87c86acb70a85b2c16f071f171847d1945e8f44812630463cd14ec83900ad01c"
dependencies = [
"zune-core 0.5.0",
"zune-core 0.5.1",
]
[[package]]

View File

@@ -1,9 +1,12 @@
[workspace.package]
version = "6.2.0"
version = "6.3.1"
rust-version = "1.82"
license = "MPL-2.0"
readme = "README.md"
authors = ["Luke <luke@ljones.dev>"]
authors = [
"Luke <luke@ljones.dev>",
"Denis Benato <benato.denis96@gmail.com>"
]
repository = "https://gitlab.com/asus-linux/asusctl"
homepage = "https://gitlab.com/asus-linux/asusctl"
description = "Laptop feature control for ASUS ROG laptops and others"

View File

@@ -13,9 +13,7 @@ Now includes a GUI, `rog-control-center`.
Due to on-going driver work the minimum suggested kernel version is always **the latest*, as improvements and fixes are continuous.
Support for some new features is not avilable unless you run a patched kernel with the work I am doing [in this github repo](https://github.com/flukejones/linux/tree/wip/ally-6.13). Use the linked branch, or `wip/ally-6.12`. Everything that is done here is upstreamed eventually (a long process).
Z13 devices will need [these](https://lore.kernel.org/linux-input/20240416090402.31057-1-luke@ljones.dev/T/#t)
Support for TDP is tied to the new asus-armoury driver: available mainline since linux 6.19: everything older is not supported.
## X11 support
@@ -180,3 +178,7 @@ Reference to any ASUS products, services, processes, or other information and/or
The use of ROG and ASUS trademarks within this website and associated tools and libraries is only to provide a recognisable identifier to users to enable them to associate that these tools will work with ASUS ROG laptops.
---
## AI Disaclaimer
Portions of this code have been written by various AI tools and reviewed by the maintainer exaclty as with every other contribution.

View File

@@ -0,0 +1,547 @@
//! LED scanning tool for discovering AniMe Matrix buffer-to-LED mappings.
//!
//! This tool lights up one buffer index at a time, allowing you to observe
//! which physical LED corresponds to each buffer position. This is essential
//! for mapping new device types like G835L where the exact layout is unknown.
//!
//! You might want to use it slowly, as it sometimes doesn't work properly.
//! Maybe there's better ways to make this reliable but for now it works for my use case.
//!
//! # Usage
//! ```
//! cargo run --example anime-led-scan -- [options]
//! ```
//!
//! # Controls
//! - `n` or `Enter`: Next index
//! - `p` or `Backspace`: Previous index
//! - `j` followed by number: Jump to specific index
//! - `+` / `-`: Adjust step size (default 1)
//! - `s`: Save current index to notes file
//! - `r`: Mark current index as row start
//! - `q` or `Ctrl+C`: Quit
//!
//! # Output
//! Creates a `led-scan-notes.txt` file with recorded observations.
use std::env;
use std::fs::OpenOptions;
use std::io::{self, BufRead, Write};
use rog_anime::usb::{get_anime_type, Brightness};
use rog_anime::{AnimeDataBuffer, AnimeType};
use rog_dbus::zbus_anime::AnimeProxyBlocking;
use zbus::blocking::Connection;
/// Saved device state for restoration on exit
struct SavedState {
builtins_enabled: bool,
brightness: Brightness,
display_enabled: bool,
}
fn print_help(scan_len: usize, buffer_len: usize) {
println!("\n=== LED Scan Tool ===");
println!(
"Scan range: 0-{} (buffer size: {})",
scan_len - 1,
buffer_len
);
println!("Commands:");
println!(" n, Enter - Next index");
println!(" p, Backspace - Previous index");
println!(" j <num> - Jump to index");
println!(" + / - - Increase/decrease step size");
println!(" s - Save note for current index");
println!(" r - Mark as row start");
println!(" a - Auto-scan (runs through all indices)");
println!(" f - Fill all buffer bytes");
println!(" f <start> <end> - Fill range (inclusive)");
println!(" p1/p2/p3 - Fill pane 1/2/3 only (each is 627 bytes)");
println!(" hold - Hold current LED (press Enter to release)");
println!(" hold <s> <e> - Hold range (press Enter to release)");
println!(" c - Clear display");
println!(" row - Step through rows (G835L, provisional)");
println!(" row <n> - Show specific row (G835L, provisional)");
println!(" allrows - Light all rows sequentially (G835L)");
println!(" rowmap - Print the full row mapping (G835L)");
println!(" h - Show this help");
println!(" q - Quit and restore state");
println!();
}
fn save_note(index: usize, note: &str) -> io::Result<()> {
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open("led-scan-notes.txt")?;
writeln!(file, "Index {}: {}", index, note)?;
Ok(())
}
fn write_single_led(
proxy: &AnimeProxyBlocking,
anime_type: AnimeType,
index: usize,
brightness: u8,
) {
let mut buffer = AnimeDataBuffer::new(anime_type);
let data = buffer.data_mut();
if index < data.len() {
data[index] = brightness;
}
if let Err(e) = proxy.write(buffer) {
eprintln!("Error writing to device: {}", e);
}
}
fn clear_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType) {
let buffer = AnimeDataBuffer::new(anime_type);
let _ = proxy.write(buffer);
}
fn fill_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType, brightness: u8) {
let mut buffer = AnimeDataBuffer::new(anime_type);
let data = buffer.data_mut();
for byte in data.iter_mut() {
*byte = brightness;
}
if let Err(e) = proxy.write(buffer) {
eprintln!("Error writing to device: {}", e);
}
}
/// Fill a range of LEDs. Both start and end are INCLUSIVE.
fn fill_range(
proxy: &AnimeProxyBlocking,
anime_type: AnimeType,
start: usize,
end: usize,
brightness: u8,
) {
let mut buffer = AnimeDataBuffer::new(anime_type);
let data = buffer.data_mut();
for i in start..=end.min(data.len().saturating_sub(1)) {
data[i] = brightness;
}
if let Err(e) = proxy.write(buffer) {
eprintln!("Error writing to device: {}", e);
}
}
fn fill_pane(proxy: &AnimeProxyBlocking, anime_type: AnimeType, pane: usize, brightness: u8) {
const PANE_LEN: usize = 627;
let start = pane * PANE_LEN;
let end = start + PANE_LEN - 1;
fill_range(proxy, anime_type, start, end, brightness);
}
/// G835L row pattern (PROVISIONAL - needs hardware verification):
/// - Rows 0-1: 1 LED each
/// - Rows 2-3: 2 LEDs each
/// - ... (pairs of rows with same length)
/// - Rows 26-27: 14 LEDs each
/// - Rows 28+: 15 LEDs each (constant)
///
/// Returns (start_index, end_index_inclusive, row_length)
fn g835l_row_bounds(row: usize) -> (usize, usize, usize) {
let triangle_rows = 28;
let triangle_leds = 210;
if row < triangle_rows {
let length = row / 2 + 1;
let mut start = 0usize;
for r in 0..row {
start += r / 2 + 1;
}
(start, start + length - 1, length)
} else {
let rows_after_triangle = row - triangle_rows;
let start = triangle_leds + rows_after_triangle * 15;
(start, start + 14, 15)
}
}
fn g835l_total_rows() -> usize {
28 + 40
}
fn save_state(proxy: &AnimeProxyBlocking) -> SavedState {
SavedState {
builtins_enabled: proxy.builtins_enabled().unwrap_or(false),
brightness: proxy.brightness().unwrap_or(Brightness::Med),
display_enabled: proxy.enable_display().unwrap_or(true),
}
}
fn restore_state(proxy: &AnimeProxyBlocking, state: &SavedState) {
let _ = proxy.set_builtins_enabled(state.builtins_enabled);
let _ = proxy.set_brightness(state.brightness);
let _ = proxy.set_enable_display(state.display_enabled);
let _ = proxy.run_main_loop(true);
}
fn main() {
let args: Vec<String> = env::args().collect();
let mut start_index = 0usize;
let mut brightness = 200u8;
let mut scan_limit: Option<usize> = None;
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--start" | "-s" => {
if i + 1 < args.len() {
start_index = args[i + 1].parse().unwrap_or(0);
i += 1;
}
}
"--brightness" | "-b" => {
if i + 1 < args.len() {
brightness = args[i + 1].parse().unwrap_or(200);
i += 1;
}
}
"--limit" | "-l" => {
if i + 1 < args.len() {
scan_limit = args[i + 1].parse().ok();
i += 1;
}
}
"--help" | "-h" => {
println!("LED Scan Tool for AniMe Matrix");
println!();
println!("Usage: anime-led-scan [options]");
println!();
println!("Options:");
println!(" -s, --start <N> Start at index N (default: 0)");
println!(" -b, --brightness <N> LED brightness 0-255 (default: 200)");
println!(" -l, --limit <N> Cap scan range to N indices (e.g. 810 for G835L)");
println!(" -h, --help Show this help");
return;
}
_ => {}
}
i += 1;
}
let conn = match Connection::system() {
Ok(c) => c,
Err(e) => {
eprintln!("Failed to connect to D-Bus: {}", e);
eprintln!("Make sure asusd is running.");
return;
}
};
let proxy = match AnimeProxyBlocking::new(&conn) {
Ok(p) => p,
Err(e) => {
eprintln!("Failed to create Anime proxy: {}", e);
eprintln!("Make sure asusd supports your device.");
return;
}
};
let anime_type = get_anime_type();
let buffer_len = anime_type.data_length();
let scan_len = scan_limit.unwrap_or(buffer_len).min(buffer_len);
println!("=== LED Scan Tool ===");
println!("Device type: {:?}", anime_type);
println!("Buffer length: {} bytes", buffer_len);
println!("Scan range: 0-{}", scan_len - 1);
println!("Brightness: {}", brightness);
println!();
// Save current state for restoration
let saved_state = save_state(&proxy);
println!("Saved device state for restoration on exit.");
// Stop system animations
if let Err(e) = proxy.run_main_loop(false) {
eprintln!("Warning: Could not stop main loop: {}", e);
}
println!("Stopped system animations.");
print_help(scan_len, buffer_len);
let mut current_index = start_index.min(scan_len - 1);
let mut step = 1usize;
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
let stdin = io::stdin();
let mut input = String::new();
loop {
input.clear();
print!("> ");
io::stdout().flush().unwrap();
if stdin.lock().read_line(&mut input).is_err() {
break;
}
let cmd = input.trim();
match cmd {
"q" | "quit" | "exit" => {
clear_display(&proxy, anime_type);
restore_state(&proxy, &saved_state);
println!("Restored device state. Goodbye!");
break;
}
"n" | "" => {
current_index = (current_index + step).min(scan_len - 1);
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
}
"p" => {
current_index = current_index.saturating_sub(step);
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
}
"+" => {
step = step.saturating_mul(2).max(1);
println!("Step size: {}", step);
}
"-" => {
step = step.saturating_div(2).max(1);
println!("Step size: {}", step);
}
"r" => {
if let Err(e) = save_note(current_index, "ROW START") {
eprintln!("Error saving note: {}", e);
} else {
println!("Saved: Index {} marked as ROW START", current_index);
}
}
"h" | "help" | "?" => {
print_help(scan_len, buffer_len);
}
cmd if cmd.starts_with('j') => {
let num_str = cmd.trim_start_matches('j').trim();
if let Ok(idx) = num_str.parse::<usize>() {
if idx < scan_len {
current_index = idx;
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
} else {
println!("Index {} out of range (max: {})", idx, scan_len - 1);
}
} else {
println!("Usage: j <number>");
}
}
cmd if cmd.starts_with('s') && !cmd.starts_with("show") => {
let note = cmd.trim_start_matches('s').trim();
let note = if note.is_empty() { "observed" } else { note };
if let Err(e) = save_note(current_index, note) {
eprintln!("Error saving note: {}", e);
} else {
println!("Saved note for index {}", current_index);
}
}
"a" => {
println!("Auto-scan mode (0 to {})...", scan_len - 1);
let delay = std::time::Duration::from_millis(10);
for idx in current_index..scan_len {
write_single_led(&proxy, anime_type, idx, brightness);
print!("\rIndex: {} / {} ", idx, scan_len - 1);
io::stdout().flush().unwrap();
std::thread::sleep(delay);
current_index = idx;
}
println!();
println!("Auto-scan complete. Current index: {}", current_index);
}
"c" => {
clear_display(&proxy, anime_type);
println!("Display cleared");
}
"f" => {
fill_display(&proxy, anime_type, brightness);
println!("All buffer bytes filled at brightness {}", brightness);
}
"p1" => {
fill_pane(&proxy, anime_type, 0, brightness);
println!("Pane 1 (indices 0-626) filled");
}
"p2" => {
fill_pane(&proxy, anime_type, 1, brightness);
println!("Pane 2 (indices 627-1253) filled");
}
"p3" => {
fill_pane(&proxy, anime_type, 2, brightness);
println!("Pane 3 (indices 1254-1880) filled");
}
cmd if cmd.starts_with("f ") => {
let parts: Vec<&str> = cmd.split_whitespace().collect();
if parts.len() == 3 {
if let (Ok(start), Ok(end)) =
(parts[1].parse::<usize>(), parts[2].parse::<usize>())
{
fill_range(&proxy, anime_type, start, end, brightness);
println!("Filled indices {} to {}", start, end);
} else {
println!("Usage: f <start> <end>");
}
} else {
println!("Usage: f <start> <end>");
}
}
"show" => {
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
}
"row" => {
if anime_type != AnimeType::G835L {
println!("Warning: Row commands use G835L mapping (provisional). You can add to this code to support other types. `examples/anime-led-scan.rs[402:425]`");
}
println!("Row stepping mode. Press Enter for next row, 'q' to quit.");
let total = g835l_total_rows();
for row_num in 0..total {
let (start, end, len) = g835l_row_bounds(row_num);
if end >= scan_len {
println!("Row {} exceeds scan limit, stopping.", row_num);
break;
}
println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len);
fill_range(&proxy, anime_type, start, end, brightness);
input.clear();
print!("(Enter=next, q=quit) > ");
io::stdout().flush().unwrap();
if stdin.lock().read_line(&mut input).is_err() {
break;
}
if input.trim() == "q" {
break;
}
clear_display(&proxy, anime_type);
}
println!("Row stepping done.");
}
cmd if cmd.starts_with("row ") => {
if anime_type != AnimeType::G835L {
println!("Warning: Row commands use G835L mapping (provisional).");
}
let row_str = cmd.trim_start_matches("row ").trim();
if let Ok(row_num) = row_str.parse::<usize>() {
let total = g835l_total_rows();
if row_num < total {
let (start, end, len) = g835l_row_bounds(row_num);
if end < scan_len {
println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len);
fill_range(&proxy, anime_type, start, end, brightness);
} else {
println!("Row {} exceeds scan limit", row_num);
}
} else {
println!("Row {} out of range (max: {})", row_num, total - 1);
}
} else {
println!("Usage: row <number>");
}
}
"allrows" => {
if anime_type != AnimeType::G835L {
println!("Warning: Row commands use G835L mapping (provisional).");
}
println!("Lighting all rows sequentially (200ms each)...");
let total = g835l_total_rows();
let delay = std::time::Duration::from_millis(200);
for row_num in 0..total {
let (start, end, len) = g835l_row_bounds(row_num);
if end >= scan_len {
println!("\nRow {} exceeds scan limit, stopping.", row_num);
break;
}
print!(
"\rRow {}/{}: indices {}-{} ({} LEDs) ",
row_num,
total - 1,
start,
end,
len
);
io::stdout().flush().unwrap();
fill_range(&proxy, anime_type, start, end, brightness);
std::thread::sleep(delay);
clear_display(&proxy, anime_type);
}
println!("\nDone.");
}
"rowmap" => {
if anime_type != AnimeType::G835L {
println!("Warning: Row map is for G835L (provisional).");
}
println!("G835L Row Map:");
let total = g835l_total_rows();
for row_num in 0..total {
let (start, end, len) = g835l_row_bounds(row_num);
let marker = if end >= scan_len {
" (exceeds limit)"
} else {
""
};
println!(
" Row {:2}: indices {:4}-{:4} ({:2} LEDs){}",
row_num, start, end, len, marker
);
}
}
"hold" => {
// Single write, wait for Enter to release
println!("Holding index {}. Press Enter to release...", current_index);
write_single_led(&proxy, anime_type, current_index, brightness);
input.clear();
let _ = stdin.lock().read_line(&mut input);
clear_display(&proxy, anime_type);
println!("Released.");
}
cmd if cmd.starts_with("hold ") => {
let arg = cmd.trim_start_matches("hold ").trim();
let (start, end): (usize, usize) = match arg {
"p1" | "1" => (0, 626),
"p2" | "2" => (627, 1253),
_ => {
let parts: Vec<&str> = arg.split_whitespace().collect();
if parts.len() == 2 {
if let (Ok(s), Ok(e)) = (parts[0].parse(), parts[1].parse()) {
(s, e)
} else {
println!("Usage: hold p1, hold p2, or hold <start> <end>");
continue;
}
} else {
println!("Usage: hold p1, hold p2, or hold <start> <end>");
continue;
}
}
};
println!("Holding range {}-{}. Press Enter to release...", start, end);
fill_range(&proxy, anime_type, start, end, brightness);
input.clear();
let _ = stdin.lock().read_line(&mut input);
clear_display(&proxy, anime_type);
println!("Released.");
}
_ => {
if let Ok(idx) = cmd.parse::<usize>() {
if idx < scan_len {
current_index = idx;
write_single_led(&proxy, anime_type, current_index, brightness);
println!(">>> Index: {} (step: {})", current_index, step);
} else {
println!("Index {} out of range (max: {})", idx, scan_len - 1);
}
} else {
println!("Unknown command: '{}'. Type 'h' for help.", cmd);
}
}
}
}
}

View File

@@ -2,7 +2,9 @@ use std::sync::Arc;
use config_traits::StdConfig;
use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
use rog_platform::asus_armoury::{
AttrValue, Attribute, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
};
use rog_platform::platform::{PlatformProfile, RogPlatform};
use rog_platform::power::AsusPower;
use serde::{Deserialize, Serialize};
@@ -168,82 +170,64 @@ impl ArmouryAttributeRegistry {
impl crate::Reloadable for AsusArmouryAttribute {
async fn reload(&mut self) -> Result<(), RogError> {
info!("Reloading {}", self.attr.name());
let name: FirmwareAttribute = self.attr.name().into();
let attribute: FirmwareAttribute = self.attr.name().into();
let name = self.attr.name();
// Treat dGPU attributes the same as PPT attributes for power-profile
// behaviour so they follow AC/DC tuning groups.
if name.is_ppt() || name.is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default()
== 1;
let apply_value = {
let config = self.config.lock().await;
config
.select_tunings_ref(power_plugged, profile)
.and_then(|tuning| {
if tuning.enabled {
tuning.group.get(&self.name()).copied()
} else {
None
}
let config = self.config.lock().await;
let apply_value = match attribute.property_type() {
FirmwareAttributeType::Ppt => {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
};
.unwrap_or_default()
== 1;
if let Some(tune) = apply_value {
self.attr
.set_current_value(&AttrValue::Integer(tune))
.map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists();
e
})?;
info!(
"Restored PPT armoury setting {} to {:?}",
self.attr.name(),
tune
);
} else {
info!("Ignored restoring PPT armoury setting {} as tuning group is disabled or no saved value", self.attr.name());
let apply_value = {
config.select_tunings_ref(power_plugged, profile).and_then(
|tuning| match tuning.enabled {
true => tuning.group.get(&self.name()).copied(),
false => None,
},
)
};
apply_value.map_or(AttrValue::None, AttrValue::Integer)
}
} else {
// Handle non-PPT attributes (boolean and other settings)
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
self.attr
.set_current_value(&AttrValue::Integer(*saved_value))
.map_err(|e| {
error!(
"Error restoring armoury setting {}: {e:?}",
self.attr.name()
);
self.attr.base_path_exists();
e
})?;
info!(
"Restored armoury setting {} to {:?}",
self.attr.name(),
saved_value
);
} else {
info!(
"No saved armoury setting for {}: skipping restore",
self.attr.name()
);
FirmwareAttributeType::Gpu => {
info!("Reload called on GPU attribute {name}: doing nothing");
AttrValue::None
}
}
_ => {
info!("Reload called on firmware attribute {name}");
match config.armoury_settings.get(&attribute) {
Some(saved_value) => AttrValue::Integer(*saved_value),
None => AttrValue::None,
}
}
};
self.attr.set_current_value(&apply_value).map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists();
e
})?;
info!(
"Restored asus-armoury setting {} to {:?}",
self.attr.name(),
apply_value
);
Ok(())
}
}
/// If return is `-1` on a property then there is avilable value for that
/// If return is `-1` on a property then there is available value for that
/// property
#[interface(name = "xyz.ljones.AsusArmoury")]
impl AsusArmouryAttribute {
@@ -293,7 +277,7 @@ impl AsusArmouryAttribute {
async fn restore_default(&self) -> fdo::Result<()> {
self.attr.restore_default()?;
if self.name().is_ppt() || self.name().is_dgpu() {
if self.name().property_type() == FirmwareAttributeType::Ppt {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
@@ -352,7 +336,7 @@ impl AsusArmouryAttribute {
#[zbus(property)]
async fn current_value(&self) -> fdo::Result<i32> {
if self.name().is_ppt() || self.name().is_dgpu() {
if self.name().property_type() == FirmwareAttributeType::Ppt {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
@@ -387,66 +371,62 @@ impl AsusArmouryAttribute {
#[zbus(property)]
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
if self.name().is_ppt() || self.name().is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default();
let mut config = self.config.lock().await;
let tuning = config.select_tunings(power_plugged == 1, profile);
if let Some(tune) = tuning.group.get_mut(&self.name()) {
*tune = value;
} else {
tuning.group.insert(self.name(), value);
debug!("Store tuning config for {} = {:?}", self.attr.name(), value);
}
if tuning.enabled {
self.attr
.set_current_value(&AttrValue::Integer(value))
let name = self.attr.name();
let apply_value = match self.name().property_type() {
FirmwareAttributeType::Ppt => {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!(
"Could not set value to PPT property {}: {e:?}",
self.attr.name()
);
error!("Could not get power status: {e:?}");
e
})?;
} else {
warn!(
"Tuning group is disabled: skipping setting value to PPT property {}",
self.attr.name()
);
}
} else {
self.attr
.set_current_value(&AttrValue::Integer(value))
.map_err(|e| {
error!(
"Could not set value {value} to attribute {}: {e:?}",
self.attr.name()
);
e
})?;
})
.unwrap_or_default();
let mut settings = self.config.lock().await;
settings
.armoury_settings
.entry(self.name())
.and_modify(|setting| {
debug!("Set config for {} = {value}", self.attr.name());
*setting = value;
})
.or_insert_with(|| {
debug!("Adding config for {} = {value}", self.attr.name());
value
});
}
let mut config = self.config.lock().await;
let tuning = config.select_tunings(power_plugged == 1, profile);
if let Some(tune) = tuning.group.get_mut(&self.name()) {
*tune = value;
} else {
tuning.group.insert(self.name(), value);
debug!("Store tuning config for {name} = {:?}", value);
}
match tuning.enabled {
true => {
debug!("Tuning is enabled: setting value to PPT property {name} = {value}");
AttrValue::Integer(value)
}
false => {
warn!("Tuning is disabled: skipping setting value to PPT property {name}");
AttrValue::None
}
}
}
_ => {
let mut settings = self.config.lock().await;
settings
.armoury_settings
.entry(self.name())
.and_modify(|setting| {
debug!("Set config for {name} = {value}");
*setting = value;
})
.or_insert_with(|| {
debug!("Adding config for {name} = {value}");
value
});
AttrValue::Integer(value)
}
};
self.attr.set_current_value(&apply_value).map_err(|e| {
error!("Could not set value {value} to attribute {name}: {e:?}");
e
})?;
// write config after setting value
self.config.lock().await.write();
@@ -515,7 +495,7 @@ pub async fn set_config_or_default(
) {
for attr in attrs.attributes().iter() {
let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() || name.is_dgpu() {
if name.property_type() == FirmwareAttributeType::Ppt {
let tuning = config.select_tunings(power_plugged, profile);
if !tuning.enabled {
debug!("Tuning group is not enabled, skipping");

View File

@@ -4,7 +4,9 @@ use std::sync::Arc;
use config_traits::StdConfig;
use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
use rog_platform::asus_armoury::{
AttrValue, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
};
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
use rog_platform::power::AsusPower;
@@ -459,8 +461,18 @@ impl CtrlPlatform {
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
policy: PlatformProfile,
) -> Result<(), FdoErr> {
self.config.lock().await.platform_profile_on_battery = policy;
self.set_platform_profile(ctxt, policy).await?;
// If the requested profile isn't available on this platform, and it's
// `Quiet`, fall back to `LowPower` so we don't write an unavailable
// profile into the config file.
let mut chosen = policy;
if let Ok(choices) = self.platform.get_platform_profile_choices() {
if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) {
chosen = PlatformProfile::LowPower;
}
}
self.config.lock().await.platform_profile_on_battery = chosen;
self.set_platform_profile(ctxt, chosen).await?;
self.config.lock().await.write();
Ok(())
}
@@ -488,8 +500,16 @@ impl CtrlPlatform {
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
policy: PlatformProfile,
) -> Result<(), FdoErr> {
self.config.lock().await.platform_profile_on_ac = policy;
self.set_platform_profile(ctxt, policy).await?;
// Mirror the same fallback behavior for AC profile changes.
let mut chosen = policy;
if let Ok(choices) = self.platform.get_platform_profile_choices() {
if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) {
chosen = PlatformProfile::LowPower;
}
}
self.config.lock().await.platform_profile_on_ac = chosen;
self.set_platform_profile(ctxt, chosen).await?;
self.config.lock().await.write();
Ok(())
}
@@ -599,7 +619,7 @@ impl CtrlPlatform {
for attr in self.attributes.attributes() {
let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() {
if name.property_type() == FirmwareAttributeType::Ppt {
// reset stored value
if let Some(tune) = self
.config

View File

@@ -20,7 +20,7 @@
%global debug_package %{nil}
%endif
%define version 6.2.0
%define version 6.3.1
%define specrelease %{?dist}
%define pkg_release 1%{specrelease}

23
extra/index.html Normal file
View File

@@ -0,0 +1,23 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>asusctl docs</title>
<!-- Redirect to the generated crate docs -->
<meta http-equiv="refresh" content="0;url=asusctl/index.html">
<link rel="canonical" href="asusctl/index.html">
<style>
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; color:#222; display:flex; align-items:center; justify-content:center; height:100vh; margin:0 }
.box { text-align:center }
a { color: #0366d6 }
</style>
</head>
<body>
<div class="box">
<h1>asusctl documentation</h1>
<p>Redirecting to the generated docs — if your browser doesn't redirect automatically, <a href="asusctl/index.html">click here</a>.</p>
<p>If you expected a different landing page, update <code>extra/index.html</code> accordingly.</p>
</div>
</body>
</html>

View File

@@ -100,8 +100,10 @@ impl AnimeType {
AnimeType::GA402
} else if board_name.contains("GU604V") {
AnimeType::GU604
} else if board_name.contains("G635L") || board_name.contains("G635L") {
} else if board_name.contains("G635L") {
AnimeType::G635L
} else if board_name.contains("G835L") {
AnimeType::G835L
} else {
AnimeType::Unsupported
}
@@ -111,7 +113,9 @@ impl AnimeType {
pub fn width(&self) -> usize {
match self {
AnimeType::GU604 => 70,
AnimeType::G835L => 74,
// TODO: Find G635L W*H
AnimeType::G635L => 68,
AnimeType::G835L => 68,
_ => 74,
}
}
@@ -121,7 +125,8 @@ impl AnimeType {
match self {
AnimeType::GA401 => 36,
AnimeType::GU604 => 43,
AnimeType::G835L => 39,
AnimeType::G635L => 34,
AnimeType::G835L => 34,
_ => 39,
}
}

View File

@@ -381,4 +381,48 @@ impl AnimeDiagonal {
AnimeDataBuffer::from_vec(crate::AnimeType::GA402, buf)
}
// TODO: Implement `to_g635l_packets` and `to_g835l_packets` functions
// fn to_g835l_packets(buf: &[u8]) -> Result<AnimeDataBuffer> {
// let mut buf = vec![0u8; AnimeType::GU604.data_length()];
// let mut start_index: usize = 0;
// fn copy_slice(
// buf: &mut [u8],
// anime: &AnimeDiagonal,
// x: usize,
// y: usize,
// start_index: &mut usize,
// len: usize,
// ) {
// buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
// *start_index += len;
// }
// let b = &mut buf;
// let a = &self;
// copy_slice(b, a, 40, 0, &mut start_index, 21);
// copy_slice(b, a, 41, 0, &mut start_index, 21);
// copy_slice(b, a, 42, 0, &mut start_index, 20);
// copy_slice(b, a, 43, 0, &mut start_index, 20);
// copy_slice(b, a, 44, 0, &mut start_index, 19);
// copy_slice(b, a, 45, 0, &mut start_index, 19);
// copy_slice(b, a, 46, 0, &mut start_index, 18);
// copy_slice(b, a, 47, 0, &mut start_index, 18);
// copy_slice(b, a, 48, 0, &mut start_index, 17);
// copy_slice(b, a, 49, 0, &mut start_index, 17);
// copy_slice(b, a, 50, 0, &mut start_index, 16);
// copy_slice(b, a, 51, 0, &mut start_index, 16);
// copy_slice(b, a, 52, 0, &mut start_index, 15);
// copy_slice(b, a, 53, 0, &mut start_index, 15);
// copy_slice(b, a, 54, 0, &mut start_index, 14);
// copy_slice(b, a, 55, 0, &mut start_index, 14);
// copy_slice(b, a, 56, 0, &mut start_index, 13);
// copy_slice(b, a, 57, 0, &mut start_index, 13);
// copy_slice(b, a, 58, 0, &mut start_index, 12);
// AnimeDataBuffer::from_vec(crate::AnimeType::G835L, buf)
// }
}

View File

@@ -138,6 +138,10 @@ impl AnimeImage {
match anime_type {
AnimeType::GA401 => 0.3,
AnimeType::GU604 => 0.28,
// TODO: Calculate correct values for G635L and G835L.
// Known values for G835L W*H is 34*68
AnimeType::G635L => 0.28,
AnimeType::G835L => 0.28,
_ => 0.283,
}
}
@@ -162,6 +166,20 @@ impl AnimeImage {
/// ^ ------+
/// first_x
/// ```
///
/// TODO: add the cases for G635L and G835L
/// This is how it looks like, but calculation may be a bit more complex
/// ```text
/// |\
/// | \
/// | \
/// | \
/// \ \
/// \ \
/// \ \
/// \ \
/// \____\
/// ```
fn first_x(anime_type: AnimeType, y: u32) -> u32 {
match anime_type {
AnimeType::GA401 => {
@@ -221,6 +239,19 @@ impl AnimeImage {
}
38 - Self::first_x(anime_type, y) + y % 2
}
// TODO: Implement this
// AnimeType::G635L => {
// if y <= 11 {
// return 34;
// }
// 39 - y / 2
// }
// AnimeType::G635E => {
// if y <= 11 {
// return 34;
// }
// 39 - y / 2
// }
_ => {
if y <= 11 {
return 34;
@@ -235,8 +266,10 @@ impl AnimeImage {
match anime_type {
// 33.0 = Longest row LED count (physical) plus half-pixel offset
AnimeType::GA401 => (33.0 + 0.5) * Self::scale_x(anime_type),
AnimeType::GU604 => (38.0 + 0.5) * Self::scale_x(anime_type),
// TODO: Implement this
// AnimeType::G635L => (34.0 + 0.5) * Self::scale_x(anime_type),
// AnimeType::G835L => (34.0 + 0.5) * Self::scale_x(anime_type),
_ => (35.0 + 0.5) * Self::scale_x(anime_type),
}
}
@@ -246,6 +279,9 @@ impl AnimeImage {
match anime_type {
AnimeType::GA401 => 55,
AnimeType::GU604 => 62,
// TODO: Implement this
// AnimeType::G635L => 68,
// AnimeType::G835L => 68,
_ => 61,
}
}
@@ -256,6 +292,11 @@ impl AnimeImage {
// 54.0 = End column LED count (physical) plus one dead pixel
AnimeType::GA401 => (54.0 + 1.0) * Self::scale_y(anime_type),
AnimeType::GU604 => 62.0 * Self::scale_y(anime_type),
// TODO: Implement this
// AnimeType::G635L => (34.0 + 0.5) * Self::scale_y(anime_type),
// AnimeType::G835L => (34.0 + 0.5) * Self::scale_y(anime_type),
// GA402 may not have dead pixels and require only the physical LED count
_ => 61.0 * Self::scale_y(anime_type),
}
@@ -269,7 +310,18 @@ impl AnimeImage {
1 | 3 => 35, // Some rows are padded
_ => 36 - y / 2,
},
// TODO: Implement this
// AnimeType::G635L => match y {
// },
// AnimeType::G835L => match y {
// },
// This seems redundant
AnimeType::GU604 => AnimeImage::width(anime_type, y),
// GA402 does not have padding, equivalent to width
_ => AnimeImage::width(anime_type, y),
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

240
rog-anime/tests/g635l.rs Normal file
View File

@@ -0,0 +1,240 @@
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use rog_anime::*;
#[test]
fn g635l_image_edge_packet_check() {
let pkt0_check = [
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let pkt1_check = [
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let mut matrix = AnimeImage::new(
Vec2::new(1.0, 1.0),
0.0,
Vec2::default(),
0.0,
vec![Pixel::default(); 1000],
100,
AnimeType::G635L,
)
.unwrap();
matrix.edge_outline();
let data = AnimeDataBuffer::try_from(&matrix).unwrap();
let pkt = AnimePacketType::try_from(data).unwrap();
// print!("left: '[");
// for b in pkt[1] {
// print!("{b:#02x},");
// }
// print!("]'");
assert_eq!(pkt[0], pkt0_check);
assert_eq!(pkt[1], pkt1_check);
}
#[test]
fn g635l_diagonal_packet_check() {
let pkt0_check = [
0x5e, 0xc0, 0x02, 0x1, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let pkt1_check = [
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
// TODO: create a png file for G635L
path.push("tests/data/ga401-diagonal.png");
let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G635L).unwrap();
let data = matrix.into_data_buffer(AnimeType::G635L).unwrap();
let pkt = AnimePacketType::try_from(data).unwrap();
assert_eq!(pkt[0], pkt0_check);
assert_eq!(pkt[1], pkt1_check);
}
}

240
rog-anime/tests/g835l.rs Normal file
View File

@@ -0,0 +1,240 @@
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use rog_anime::*;
#[test]
fn g835l_image_edge_packet_check() {
let pkt0_check = [
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let pkt1_check = [
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let mut matrix = AnimeImage::new(
Vec2::new(1.0, 1.0),
0.0,
Vec2::default(),
0.0,
vec![Pixel::default(); 1000],
100,
AnimeType::G835L,
)
.unwrap();
matrix.edge_outline();
let data = AnimeDataBuffer::try_from(&matrix).unwrap();
let pkt = AnimePacketType::try_from(data).unwrap();
// print!("left: '[");
// for b in pkt[1] {
// print!("{b:#02x},");
// }
// print!("]'");
assert_eq!(pkt[0], pkt0_check);
assert_eq!(pkt[1], pkt1_check);
}
#[test]
fn g835l_diagonal_packet_check() {
let pkt0_check = [
0x5e, 0xc0, 0x02, 0x1, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let pkt1_check = [
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
// TODO: create a png file for G835L
path.push("tests/data/ga401-diagonal.png");
let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G835L).unwrap();
let data = matrix.into_data_buffer(AnimeType::G835L).unwrap();
let pkt = AnimePacketType::try_from(data).unwrap();
assert_eq!(pkt[0], pkt0_check);
assert_eq!(pkt[1], pkt1_check);
}
}

View File

@@ -332,6 +332,15 @@
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
device_name: "G615LR",
product_id: "",
layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
device_name: "G634J",
product_id: "",
@@ -566,6 +575,15 @@
advanced_type: PerKey,
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
),
(
device_name: "G835L",
product_id: "",
layout_name: "g814ji-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Comet, Flash],
basic_zones: [],
advanced_type: PerKey,
power_zones: [Keyboard, Lightbar, Logo],
),
(
device_name: "GA401I",
product_id: "",

View File

@@ -14,6 +14,7 @@ mocking = []
x11 = ["slint/backend-winit-x11"]
# Optional tokio debug feature does not require nightly; remove RUSTFLAGS note.
tokio-debug = ["console-subscriber"]
rog_ally = []
[dependencies]
console-subscriber = { version = "^0.4", optional = true }

View File

@@ -107,7 +107,6 @@ async fn main() -> Result<()> {
let board_name = dmi.board_name;
let prod_family = dmi.product_family;
info!("Running on {board_name}, product: {prod_family}");
let is_rog_ally = board_name == "RC71L" || board_name == "RC72L" || prod_family == "ROG Ally";
let args: Vec<String> = args().skip(1).collect();
@@ -138,6 +137,18 @@ async fn main() -> Result<()> {
config.start_fullscreen = false;
}
let is_rog_ally = {
#[cfg(feature = "rog_ally")]
{
board_name == "RC71L" || board_name == "RC72L" || prod_family == "ROG Ally"
}
#[cfg(not(feature = "rog_ally"))]
{
false
}
};
#[cfg(feature = "rog_ally")]
if is_rog_ally {
config.notifications.enabled = false;
config.enable_tray_icon = false;
@@ -145,6 +156,7 @@ async fn main() -> Result<()> {
config.startup_in_background = false;
config.start_fullscreen = true;
}
config.write();
let enable_tray_icon = config.enable_tray_icon;
@@ -203,76 +215,77 @@ async fn main() -> Result<()> {
}
})
.ok();
} else {
// save as a var, don't hold the lock the entire time or deadlocks happen
if let Ok(app_state) = app_state.lock() {
state = *app_state;
continue;
}
// save as a var, don't hold the lock the entire time or deadlocks happen
if let Ok(app_state) = app_state.lock() {
state = *app_state;
}
// This sleep is required to give the event loop time to react
sleep(Duration::from_millis(300));
if state == AppState::MainWindowShouldOpen {
if let Ok(mut app_state) = app_state.lock() {
*app_state = AppState::MainWindowOpen;
}
// This sleep is required to give the event loop time to react
sleep(Duration::from_millis(300));
if state == AppState::MainWindowShouldOpen {
if let Ok(mut app_state) = app_state.lock() {
*app_state = AppState::MainWindowOpen;
}
let config_copy = config.clone();
let app_state_copy = app_state.clone();
slint::invoke_from_event_loop(move || {
UI.with(|ui| {
let app_state_copy = app_state_copy.clone();
let mut ui = ui.borrow_mut();
if let Some(ui) = ui.as_mut() {
ui.window().show().unwrap();
ui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() {
*app_state = AppState::MainWindowClosed;
}
slint::CloseRequestResponse::HideWindow
});
} else {
let config_copy_2 = config_copy.clone();
let newui = setup_window(config_copy);
newui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() {
*app_state = AppState::MainWindowClosed;
}
slint::CloseRequestResponse::HideWindow
});
let config_copy = config.clone();
let app_state_copy = app_state.clone();
slint::invoke_from_event_loop(move || {
UI.with(|ui| {
let app_state_copy = app_state_copy.clone();
let mut ui = ui.borrow_mut();
if let Some(ui) = ui.as_mut() {
ui.window().show().unwrap();
ui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() {
*app_state = AppState::MainWindowClosed;
let ui_copy = newui.as_weak();
newui
.window()
.set_rendering_notifier(move |s, _| {
if let slint::RenderingState::RenderingSetup = s {
let config = config_copy_2.clone();
ui_copy
.upgrade_in_event_loop(move |w| {
let fullscreen =
config.lock().is_ok_and(|c| c.start_fullscreen);
if fullscreen && !w.window().is_fullscreen() {
w.window().set_fullscreen(fullscreen);
}
})
.ok();
}
slint::CloseRequestResponse::HideWindow
});
} else {
let config_copy_2 = config_copy.clone();
let newui = setup_window(config_copy);
newui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() {
*app_state = AppState::MainWindowClosed;
}
slint::CloseRequestResponse::HideWindow
});
let ui_copy = newui.as_weak();
newui
.window()
.set_rendering_notifier(move |s, _| {
if let slint::RenderingState::RenderingSetup = s {
let config = config_copy_2.clone();
ui_copy
.upgrade_in_event_loop(move |w| {
let fullscreen = config
.lock()
.is_ok_and(|c| c.start_fullscreen);
if fullscreen && !w.window().is_fullscreen() {
w.window().set_fullscreen(fullscreen);
}
})
.ok();
}
})
.ok();
ui.replace(newui);
}
});
})
.unwrap();
} else if state == AppState::QuitApp {
slint::quit_event_loop().unwrap();
exit(0);
} else if state != AppState::MainWindowOpen {
if let Ok(config) = config.lock() {
if !config.run_in_background {
slint::quit_event_loop().unwrap();
exit(0);
})
.ok();
ui.replace(newui);
}
});
})
.unwrap();
} else if state == AppState::QuitApp {
slint::quit_event_loop().unwrap();
exit(0);
} else if state != AppState::MainWindowOpen {
if let Ok(config) = config.lock() {
if !config.run_in_background {
slint::quit_event_loop().unwrap();
exit(0);
}
}
}

View File

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

View File

@@ -102,8 +102,9 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
available.contains(&"xyz.ljones.Aura".to_string()),
available.contains(&"xyz.ljones.Anime".to_string()),
available.contains(&"xyz.ljones.FanCurves".to_string()),
true,
true,
true, // GPU Configuration
true, // App Settings
true, // About
]
.into(),
);

View File

@@ -0,0 +1,810 @@
msgid ""
msgstr ""
"Project-Id-Version: rog-control-center\n"
"POT-Creation-Date: 2026-01-16 22:25+0000\n"
"PO-Revision-Date: 2024-07-28 12:00+0300\n"
"Last-Translator: Mykola Shevchenko\n"
"Language-Team: Ukrainian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: uk_UA\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: rog-control-center/ui/main_window.slint:55
msgctxt "MainWindow"
msgid "ROG"
msgstr "ROG"
#: rog-control-center/ui/main_window.slint:57
msgctxt "Menu1"
msgid "System Control"
msgstr "Системні"
#: rog-control-center/ui/main_window.slint:58
msgctxt "Menu2"
msgid "Keyboard Aura"
msgstr "Aura клавіатури"
#: rog-control-center/ui/main_window.slint:59
msgctxt "Menu3"
msgid "AniMe Matrix"
msgstr "AniMe матриця"
#: rog-control-center/ui/main_window.slint:60
msgctxt "Menu4"
msgid "Fan Curves"
msgstr "Криві вентиляторів"
#: rog-control-center/ui/main_window.slint:61
msgctxt "Menu5"
msgid "App Settings"
msgstr "Налаштування"
#: rog-control-center/ui/main_window.slint:62
msgctxt "Menu6"
msgid "About"
msgstr "Про додаток"
#: rog-control-center/ui/main_window.slint:74
msgctxt "MainWindow"
msgid "Quit App"
msgstr "Вийти"
#: rog-control-center/ui/pages/anime.slint:6
msgctxt "Anime Brightness"
msgid "Off"
msgstr "Вимкнено"
#: rog-control-center/ui/pages/anime.slint:7
msgctxt "Anime Brightness"
msgid "Low"
msgstr "Низька"
#: rog-control-center/ui/pages/anime.slint:8
msgctxt "Anime Brightness"
msgid "Med"
msgstr "Середня"
#: rog-control-center/ui/pages/anime.slint:9
msgctxt "Anime Brightness"
msgid "High"
msgstr "Висока"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Glitch Construction"
msgstr "Збій конструкції"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Static Emergence"
msgstr "Статична поява"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Binary Banner Scroll"
msgstr "Прокрутка бінарного банера"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Rog Logo Glitch"
msgstr "Збій логотипу Rog"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Banner Swipe"
msgstr "Прогортання банера"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Starfield"
msgstr "Зоряне поле"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "Glitch Out"
msgstr "Збій"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "See Ya"
msgstr "Бувай"
#: rog-control-center/ui/pages/anime.slint:50
msgctxt "Anime Brightness"
msgid "Brightness"
msgstr "Яскравість"
#: rog-control-center/ui/pages/anime.slint:66
msgctxt "PageAnime"
msgid "Enable display"
msgstr "Увімкнути показ"
#: rog-control-center/ui/pages/anime.slint:74 rog-control-center/ui/pages/anime.slint:97
msgctxt "PageAnime"
msgid "Advanced"
msgstr "Розширені"
#: rog-control-center/ui/pages/anime.slint:89
msgctxt "PageAnime"
msgid "Use built-in animations"
msgstr "Використовувати вбудовані анімації"
#: rog-control-center/ui/pages/anime.slint:146
msgctxt "PageAnime"
msgid "Set which builtin animations are played"
msgstr "Встановити, які вбудовані анімації відтворювати"
#: rog-control-center/ui/pages/anime.slint:150
msgctxt "Anime built-in selection"
msgid "Boot Animation"
msgstr "Анімація завантаження"
#: rog-control-center/ui/pages/anime.slint:160
msgctxt "Anime built-in selection"
msgid "Running Animation"
msgstr "Анімація роботи"
#: rog-control-center/ui/pages/anime.slint:170
msgctxt "Anime built-in selection"
msgid "Sleep Animation"
msgstr "Анімація сну"
#: rog-control-center/ui/pages/anime.slint:180
msgctxt "Anime built-in selection"
msgid "Shutdown Animation"
msgstr "Анімація вимкнення"
#: rog-control-center/ui/pages/anime.slint:220
msgctxt "PageAnime"
msgid "Advanced Display Settings"
msgstr "Розширені налаштування показу"
#: rog-control-center/ui/pages/anime.slint:225
msgctxt "PageAnime"
msgid "Off when lid closed"
msgstr "Вимикати при закритій кришці"
#: rog-control-center/ui/pages/anime.slint:234
msgctxt "PageAnime"
msgid "Off when suspended"
msgstr "Вимикати в режимі сну"
#: rog-control-center/ui/pages/anime.slint:243
msgctxt "PageAnime"
msgid "Off when on battery"
msgstr "Вимикати при роботі від батареї"
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Balanced"
msgstr "Збалансований"
#: rog-control-center/ui/pages/system.slint:20 rog-control-center/ui/pages/system.slint:27
msgctxt "SystemPageData"
msgid "Performance"
msgstr "Продуктивний"
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Quiet"
msgstr "Тихий"
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "LowPower"
msgstr "Низьке споживання"
#: rog-control-center/ui/pages/system.slint:26
msgctxt "SystemPageData"
msgid "Default"
msgstr "За замовчуванням"
#: rog-control-center/ui/pages/system.slint:28
msgctxt "SystemPageData"
msgid "BalancePerformance"
msgstr "Баланс-Продуктивність"
#: rog-control-center/ui/pages/system.slint:29
msgctxt "SystemPageData"
msgid "BalancePower"
msgstr "Баланс-Енергозбереження"
#: rog-control-center/ui/pages/system.slint:30
msgctxt "SystemPageData"
msgid "Power"
msgstr "Енергозбереження"
#: rog-control-center/ui/pages/system.slint:159
msgctxt "PageSystem"
msgid "Power settings"
msgstr "Налаштування живлення"
#: rog-control-center/ui/pages/system.slint:164
msgctxt "PageSystem"
msgid "Charge limit"
msgstr "Ліміт заряду"
#: rog-control-center/ui/pages/system.slint:179
msgctxt "PageSystem"
msgid "Platform Profile"
msgstr "Профіль платформи"
#: rog-control-center/ui/pages/system.slint:189
msgctxt "PageSystem"
msgid "Advanced"
msgstr "Розширені"
#: rog-control-center/ui/pages/system.slint:209
msgctxt "PageSystem"
msgid "Screenpad brightness"
msgstr "Яскравість екранної панелі"
#: rog-control-center/ui/pages/system.slint:233
msgctxt "PageSystem"
msgid "Sync with primary"
msgstr "Синхронізувати з основним"
#: rog-control-center/ui/pages/system.slint:253
msgctxt "PageSystem"
msgid "Armoury settings"
msgstr "Налаштування Armoury"
#: rog-control-center/ui/pages/system.slint:253
msgctxt "PageSystem"
msgid "Keyboard Power Management"
msgstr "Керування живленням клавіатури"
#: rog-control-center/ui/pages/system.slint:263
msgctxt "no_asus_armoury_driver_1"
msgid "The asus-armoury driver is not loaded"
msgstr "Драйвер asus-armoury не завантажено"
#: rog-control-center/ui/pages/system.slint:269
msgctxt "no_asus_armoury_driver_2"
msgid "For advanced features you will require a kernel with this driver added."
msgstr "Для розширених функцій вам знадобиться ядро з доданим цим драйвером."
#: rog-control-center/ui/pages/system.slint:280
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr "Розгін матриці"
#: rog-control-center/ui/pages/system.slint:288
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr "Режим MiniLED"
#: rog-control-center/ui/pages/system.slint:296
msgctxt "PageSystem"
msgid "POST boot sound"
msgstr "Звук при завантаженні"
#: rog-control-center/ui/pages/system.slint:312
msgctxt "ppt_warning"
msgid "The following settings are not applied until the toggle is enabled."
msgstr "Наступні налаштування не застосовуються, доки перемикач не буде увімкнено."
#: rog-control-center/ui/pages/system.slint:317 rog-control-center/ui/pages/system.slint:324
msgctxt "ppt_group_enabled"
msgid "Enable Tuning"
msgstr "Увімкнути налаштування"
#: rog-control-center/ui/pages/system.slint:334 rog-control-center/ui/pages/system.slint:335
msgctxt "ppt_pl1_spl"
msgid "CPU Sustained Power Limit"
msgstr "Тривалий ліміт потужності CPU"
#: rog-control-center/ui/pages/system.slint:336
msgctxt "ppt_pl1_spl_help"
msgid ""
"Long-term CPU power limit that affects sustained workload performance. "
"Higher values may increase heat and power consumption."
msgstr ""
"Довготривалий ліміт потужності CPU, що впливає на продуктивність при тривалих навантаженнях."
"Вищі значення можуть збільшити нагрівання та споживання енергії."
#: rog-control-center/ui/pages/system.slint:352 rog-control-center/ui/pages/system.slint:353
msgctxt "ppt_pl2_sppt"
msgid "CPU Turbo Power Limit"
msgstr "Турбо ліміт потужності CPU"
#: rog-control-center/ui/pages/system.slint:354
msgctxt "ppt_pl2_sppt_help"
msgid ""
"Short-term CPU power limit for boost periods. Controls maximum power during "
"brief high-performance bursts."
msgstr ""
"Короткочасний ліміт потужності CPU для періодів прискорення. Контролює максимальну"
"потужність під час коротких сплесків високої продуктивності."
#: rog-control-center/ui/pages/system.slint:370 rog-control-center/ui/pages/system.slint:371
msgctxt "ppt_pl3_fppt"
msgid "CPU Fast Burst Power Limit"
msgstr "Швидкий ліміт потужності CPU"
#: rog-control-center/ui/pages/system.slint:372
msgctxt "ppt_pl3_fppt_help"
msgid ""
"Ultra-short duration power limit for instantaneous CPU bursts. Affects "
"responsiveness during sudden workload spikes."
msgstr ""
"Надкороткий ліміт потужності для миттєвих сплесків CPU."
"Впливає на чутливість під час раптових піків навантаження."
#: rog-control-center/ui/pages/system.slint:387 rog-control-center/ui/pages/system.slint:388
msgctxt "ppt_fppt"
msgid "Fast Package Power Limit"
msgstr "Швидкий ліміт потужності пакета"
#: rog-control-center/ui/pages/system.slint:389
msgctxt "ppt_fppt_help"
msgid ""
"Ultra-short duration power limit for system package. Controls maximum power "
"during millisecond-scale load spikes."
msgstr ""
"Надкороткий ліміт потужності для системного пакета. Контролює максимальну"
"потужність під час пікових навантажень мілісекундного масштабу."
#: rog-control-center/ui/pages/system.slint:405 rog-control-center/ui/pages/system.slint:406
msgctxt "ppt_apu_sppt"
msgid "APU Sustained Power Limit"
msgstr "Тривалий ліміт потужності APU"
#: rog-control-center/ui/pages/system.slint:407
msgctxt "ppt_apu_sppt_help"
msgid ""
"Long-term power limit for integrated graphics and CPU combined. Affects "
"sustained performance of APU-based workloads."
msgstr ""
"Довготривалий ліміт потужності для інтегрованої графіки та CPU разом."
"Впливає на тривалу продуктивність навантажень на базі APU."
#: rog-control-center/ui/pages/system.slint:423 rog-control-center/ui/pages/system.slint:424
msgctxt "ppt_platform_sppt"
msgid "Platform Sustained Power Limit"
msgstr "Тривалий ліміт потужності платформи"
#: rog-control-center/ui/pages/system.slint:425
msgctxt "ppt_platform_sppt_help"
msgid ""
"Overall system power limit for sustained operations. Controls total platform "
"power consumption over extended periods."
msgstr ""
"Загальний ліміт потужності системи для тривалих операцій. Контролює загальне"
"споживання енергії платформою протягом тривалих періодів."
#: rog-control-center/ui/pages/system.slint:441 rog-control-center/ui/pages/system.slint:442
msgctxt "nv_dynamic_boost"
msgid "GPU Power Boost"
msgstr "Прискорення потужності GPU"
#: rog-control-center/ui/pages/system.slint:443
msgctxt "nv_dynamic_boost_help"
msgid ""
"Additional power allocation for GPU dynamic boost. Higher values increase "
"GPU performance but generate more heat."
msgstr ""
"Додаткове виділення потужності для динамічного прискорення GPU. Вищі значення"
"збільшують продуктивність GPU, але генерують більше тепла."
#: rog-control-center/ui/pages/system.slint:459 rog-control-center/ui/pages/system.slint:460
msgctxt "nv_temp_target"
msgid "GPU Temperature Limit"
msgstr "Ліміт температури GPU"
#: rog-control-center/ui/pages/system.slint:461
msgctxt "nv_temp_target_help"
msgid ""
"Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain "
"temperature below this limit."
msgstr ""
"Максимальний поріг температури GPU у градусах Цельсія. GPU буде знижувати"
"частоту для підтримки температури нижче цього ліміту."
#: rog-control-center/ui/pages/system.slint:513
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr "Перевага енергоефективності пов'язана з Політикою Тротлінгу"
#: rog-control-center/ui/pages/system.slint:517
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr "Змінювати EPP на основі Політики Тротлінгу"
#: rog-control-center/ui/pages/system.slint:525
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr "EPP для Збалансованої Політики"
#: rog-control-center/ui/pages/system.slint:535
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr "EPP для Політики Продуктивності"
#: rog-control-center/ui/pages/system.slint:545
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr "EPP для Тихої Політики"
#: rog-control-center/ui/pages/system.slint:563
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr "Політика Тротлінгу для стану живлення"
#: rog-control-center/ui/pages/system.slint:569
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr "Політика Тротлінгу при живленні від батареї"
#: rog-control-center/ui/pages/system.slint:579 rog-control-center/ui/pages/system.slint:600
msgctxt "PageSystem"
msgid "Enabled"
msgstr "Увімкнено"
#: rog-control-center/ui/pages/system.slint:590
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr "Політика Тротлінгу при живленні від мережі"
#: rog-control-center/ui/pages/aura.slint:28
msgctxt "PageAura"
msgid "Brightness"
msgstr "Яскравість"
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "PageAura"
msgid "Aura mode"
msgstr "Режим Aura"
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "PageAura"
msgid "Colour 1"
msgstr "Колір 1"
#: rog-control-center/ui/pages/aura.slint:85
msgctxt "PageAura"
msgid "Colour 2"
msgstr "Колір 2"
#: rog-control-center/ui/pages/aura.slint:119
msgctxt "PageAura"
msgid "Zone"
msgstr "Зона"
#: rog-control-center/ui/pages/aura.slint:142
msgctxt "PageAura"
msgid "Direction"
msgstr "Напрямок"
#: rog-control-center/ui/pages/aura.slint:164
msgctxt "PageAura"
msgid "Speed"
msgstr "Швидкість"
#: rog-control-center/ui/pages/aura.slint:185
msgctxt "PageAura"
msgid "Power Settings"
msgstr "Налаштування живлення"
#: rog-control-center/ui/pages/aura.slint:270
msgctxt "PageAura"
msgid "Power Zones"
msgstr "Зони живлення"
#: rog-control-center/ui/pages/app_settings.slint:26
msgctxt "PageAppSettings"
msgid "Run in background after closing"
msgstr "Працювати у фоні після закриття"
#: rog-control-center/ui/pages/app_settings.slint:34
msgctxt "PageAppSettings"
msgid "Start app in background (UI closed)"
msgstr "Запускати у фоні (без інтерфейсу)"
#: rog-control-center/ui/pages/app_settings.slint:42
msgctxt "PageAppSettings"
msgid "Enable system tray icon"
msgstr "Увімкнути іконку в треї"
#: rog-control-center/ui/pages/app_settings.slint:50
msgctxt "PageAppSettings"
msgid "Enable dGPU notifications"
msgstr "Увімкнути сповіщення про dGPU"
#: rog-control-center/ui/pages/fans.slint:26
msgctxt "FanTab"
msgid "This fan is not avilable on this machine"
msgstr "Цей вентилятор недоступний на цьому пристрої"
#: rog-control-center/ui/pages/fans.slint:34
msgctxt "FanTab"
msgid "Enabled"
msgstr "Увімкнено"
#: rog-control-center/ui/pages/fans.slint:43
msgctxt "FanTab"
msgid "Apply"
msgstr "Застосувати"
#: rog-control-center/ui/pages/fans.slint:51
msgctxt "FanTab"
msgid "Cancel"
msgstr "Скасувати"
#: rog-control-center/ui/pages/fans.slint:59
msgctxt "FanTab"
msgid "Factory Default (all fans)"
msgstr "Заводські налаштування (всі вентилятори)"
#: rog-control-center/ui/pages/fans.slint:72
msgctxt "PageFans"
msgid "Balanced"
msgstr "Збалансований"
#: rog-control-center/ui/pages/fans.slint:75 rog-control-center/ui/pages/fans.slint:134 rog-control-center/ui/pages/fans.slint:193
msgctxt "PageFans"
msgid "CPU"
msgstr "CPU"
#: rog-control-center/ui/pages/fans.slint:93 rog-control-center/ui/pages/fans.slint:152 rog-control-center/ui/pages/fans.slint:211
msgctxt "PageFans"
msgid "Mid"
msgstr "Середній"
#: rog-control-center/ui/pages/fans.slint:111 rog-control-center/ui/pages/fans.slint:170 rog-control-center/ui/pages/fans.slint:229
msgctxt "PageFans"
msgid "GPU"
msgstr "GPU"
#: rog-control-center/ui/pages/fans.slint:131
msgctxt "PageFans"
msgid "Performance"
msgstr "Продуктивний"
#: rog-control-center/ui/pages/fans.slint:190
msgctxt "PageFans"
msgid "Quiet"
msgstr "Тихий"
#: rog-control-center/ui/widgets/common.slint:126
msgctxt "confirm_reset"
msgid "Are you sure you want to reset this?"
msgstr "Ви впевнені, що хочете скинути це?"
#: rog-control-center/ui/widgets/aura_power.slint:33
msgctxt "AuraPowerGroup"
msgid "Boot"
msgstr "Запуск"
#: rog-control-center/ui/widgets/aura_power.slint:43
msgctxt "AuraPowerGroup"
msgid "Awake"
msgstr "Робота"
#: rog-control-center/ui/widgets/aura_power.slint:53
msgctxt "AuraPowerGroup"
msgid "Sleep"
msgstr "Сон"
#: rog-control-center/ui/widgets/aura_power.slint:63
msgctxt "AuraPowerGroup"
msgid "Shutdown"
msgstr "Вимкнення"
#: rog-control-center/ui/widgets/aura_power.slint:102
msgctxt "AuraPowerGroupOld"
msgid "Zone Selection"
msgstr "Вибір зони"
#: rog-control-center/ui/widgets/aura_power.slint:114
msgctxt "AuraPowerGroupOld"
msgid "Boot"
msgstr "Завантаження"
#: rog-control-center/ui/widgets/aura_power.slint:124
msgctxt "AuraPowerGroupOld"
msgid "Awake"
msgstr "Робота"
#: rog-control-center/ui/widgets/aura_power.slint:134
msgctxt "AuraPowerGroupOld"
msgid "Sleep"
msgstr "Сон"
#: rog-control-center/ui/types/aura_types.slint:52
msgctxt "Aura power zone"
msgid "Logo"
msgstr "Логотип"
#: rog-control-center/ui/types/aura_types.slint:53 rog-control-center/ui/types/aura_types.slint:63
msgctxt "Aura power zone"
msgid "Keyboard"
msgstr "Клавіатура"
#: rog-control-center/ui/types/aura_types.slint:54 rog-control-center/ui/types/aura_types.slint:64
msgctxt "Aura power zone"
msgid "Lightbar"
msgstr "Світлова панель"
#: rog-control-center/ui/types/aura_types.slint:55
msgctxt "Aura power zone"
msgid "Lid"
msgstr "Кришка"
#: rog-control-center/ui/types/aura_types.slint:56
msgctxt "Aura power zone"
msgid "Rear Glow"
msgstr "Заднє світіння"
#: rog-control-center/ui/types/aura_types.slint:57 rog-control-center/ui/types/aura_types.slint:65
msgctxt "Aura power zone"
msgid "Keyboard and Lightbar"
msgstr "Клавіатура та світлова панель"
#: rog-control-center/ui/types/aura_types.slint:58
msgctxt "Aura power zone"
msgid "Ally"
msgstr "Ally"
#: rog-control-center/ui/types/aura_types.slint:68
msgctxt "Aura brightness"
msgid "Off"
msgstr "Вимкнено"
#: rog-control-center/ui/types/aura_types.slint:69
msgctxt "Aura brightness"
msgid "Low"
msgstr "Низька"
#: rog-control-center/ui/types/aura_types.slint:70
msgctxt "Aura brightness"
msgid "Med"
msgstr "Середня"
#: rog-control-center/ui/types/aura_types.slint:71
msgctxt "Aura brightness"
msgid "High"
msgstr "Висока"
#: rog-control-center/ui/types/aura_types.slint:76 rog-control-center/ui/types/aura_types.slint:91
msgctxt "Basic aura mode"
msgid "Static"
msgstr "Статичний"
#: rog-control-center/ui/types/aura_types.slint:77 rog-control-center/ui/types/aura_types.slint:92
msgctxt "Basic aura mode"
msgid "Breathe"
msgstr "Дихання"
#: rog-control-center/ui/types/aura_types.slint:78 rog-control-center/ui/types/aura_types.slint:93
msgctxt "Basic aura mode"
msgid "Strobe"
msgstr "Стробоскоп"
#: rog-control-center/ui/types/aura_types.slint:79
msgctxt "Basic aura mode"
msgid "Rainbow"
msgstr "Веселка"
#: rog-control-center/ui/types/aura_types.slint:80
msgctxt "Basic aura mode"
msgid "Star"
msgstr "Зірка"
#: rog-control-center/ui/types/aura_types.slint:81
msgctxt "Basic aura mode"
msgid "Rain"
msgstr "Дощ"
#: rog-control-center/ui/types/aura_types.slint:82
msgctxt "Basic aura mode"
msgid "Highlight"
msgstr "Підсвічування"
#: rog-control-center/ui/types/aura_types.slint:83
msgctxt "Basic aura mode"
msgid "Laser"
msgstr "Лазер"
#: rog-control-center/ui/types/aura_types.slint:84
msgctxt "Basic aura mode"
msgid "Ripple"
msgstr "Хвиля"
#: rog-control-center/ui/types/aura_types.slint:85
msgctxt "Basic aura mode"
msgid "Nothing"
msgstr "Нічого"
#: rog-control-center/ui/types/aura_types.slint:86
msgctxt "Basic aura mode"
msgid "Pulse"
msgstr "Пульс"
#: rog-control-center/ui/types/aura_types.slint:87
msgctxt "Basic aura mode"
msgid "Comet"
msgstr "Комета"
#: rog-control-center/ui/types/aura_types.slint:88
msgctxt "Basic aura mode"
msgid "Flash"
msgstr "Спалах"
#: rog-control-center/ui/types/aura_types.slint:100
msgctxt "Aura zone"
msgid "None"
msgstr "Немає"
#: rog-control-center/ui/types/aura_types.slint:101
msgctxt "Aura zone"
msgid "Key1"
msgstr "Клавіша 1"
#: rog-control-center/ui/types/aura_types.slint:102
msgctxt "Aura zone"
msgid "Key2"
msgstr "Клавіша 2"
#: rog-control-center/ui/types/aura_types.slint:103
msgctxt "Aura zone"
msgid "Key3"
msgstr "Клавіша 3"
#: rog-control-center/ui/types/aura_types.slint:104
msgctxt "Aura zone"
msgid "Key4"
msgstr "Клавіша 4"
#: rog-control-center/ui/types/aura_types.slint:105
msgctxt "Aura zone"
msgid "Logo"
msgstr "Логотип"
#: rog-control-center/ui/types/aura_types.slint:106
msgctxt "Aura zone"
msgid "Lightbar Left"
msgstr "Світлова панель зліва"
#: rog-control-center/ui/types/aura_types.slint:107
msgctxt "Aura zone"
msgid "Lightbar Right"
msgstr "Світлова панель справа"
#: rog-control-center/ui/types/aura_types.slint:111
msgctxt "Aura direction"
msgid "Right"
msgstr "Вправо"
#: rog-control-center/ui/types/aura_types.slint:112
msgctxt "Aura direction"
msgid "Left"
msgstr "Вліво"
#: rog-control-center/ui/types/aura_types.slint:113
msgctxt "Aura direction"
msgid "Up"
msgstr "Вгору"
#: rog-control-center/ui/types/aura_types.slint:114
msgctxt "Aura direction"
msgid "Down"
msgstr "Вниз"
#: rog-control-center/ui/types/aura_types.slint:118
msgctxt "Aura speed"
msgid "Low"
msgstr "Низька"
#: rog-control-center/ui/types/aura_types.slint:119
msgctxt "Aura speed"
msgid "Medium"
msgstr "Середня"
#: rog-control-center/ui/types/aura_types.slint:120
msgctxt "Aura speed"
msgid "High"
msgstr "Висока"

View File

@@ -7,6 +7,7 @@ import { PageFans } from "pages/fans.slint";
import { PageAnime, AnimePageData } from "pages/anime.slint";
import { RogItem } from "widgets/common.slint";
import { PageAura } from "pages/aura.slint";
import { PageGPU } from "pages/gpu.slint";
import { Node } from "widgets/graph.slint";
export { Node }
import { FanPageData, FanType, Profile } from "types/fan_types.slint";
@@ -24,7 +25,15 @@ export component MainWindow inherits Window {
default-font-size: 14px;
default-font-weight: 400;
icon: @image-url("../data/rog-control-center.png");
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true];
in property <[bool]> sidebar_items_avilable: [
true,
true,
true,
true,
true, // GPU Configuration
true, // App Settings
true, // About
];
private property <bool> show_notif;
private property <bool> fade_cover;
private property <bool> toast: false;
@@ -58,8 +67,9 @@ export component MainWindow inherits Window {
@tr("Menu2" => "Keyboard Aura"),
@tr("Menu3" => "AniMe Matrix"),
@tr("Menu4" => "Fan Curves"),
@tr("Menu5" => "App Settings"),
@tr("Menu6" => "About"),
@tr("Menu5" => "GPU Configuration"),
@tr("Menu6" => "App Settings"),
@tr("Menu7" => "About"),
];
available: root.sidebar_items_avilable;
}
@@ -89,26 +99,61 @@ export component MainWindow inherits Window {
height: root.height + 12px;
}
aura := PageAura {
/*if(side-bar.current-item == 1):*/ aura := PageAura {
width: root.width - side-bar.width;
visible: side-bar.current-item == 1;
}
if(side-bar.current-item == 2): PageAnime {
width: root.width - side-bar.width;
visible: side-bar.current-item == 2;
}
fans := PageFans {
if(side-bar.current-item == 3): fans := PageFans {
width: root.width - side-bar.width;
visible: side-bar.current-item == 3;
}
if(side-bar.current-item == 4): PageAppSettings {
if(side-bar.current-item == 4): PageGPU {
width: root.width - side-bar.width;
visible: side-bar.current-item == 4;
}
if(side-bar.current-item == 5): PageAbout {
if(side-bar.current-item == 5): PageAppSettings {
width: root.width - side-bar.width;
visible: side-bar.current-item == 5;
}
if(side-bar.current-item == 6): PageAbout {
width: root.width - side-bar.width;
visible: side-bar.current-item == 6;
}
if toast: Rectangle {
x: 0px;
y: root.height - self.height;
width: root.width - side-bar.width;
height: 40px;
opacity: 1.0;
background: Palette.selection-background;
clip: true;
TouchArea {
height: 100%;
width: 100%;
clicked => {
toast = false;
}
}
Rectangle {
height: 100%;
width: 100%;
background: Palette.control-background;
Text {
color: Palette.control-foreground;
text: root.toast_text;
}
}
}
}
}
@@ -133,31 +178,6 @@ export component MainWindow inherits Window {
}
}
if toast: Rectangle {
x: 0px;
y: 0px;
width: root.width;
height: 32px;
opacity: 1.0;
background: Colors.grey;
TouchArea {
height: 100%;
width: 100%;
clicked => {
toast = false;
}
}
Rectangle {
height: 100%;
width: 100%;
background: Palette.control-background;
Text {
color: Palette.control-foreground;
text: root.toast_text;
}
}
}
// // TODO: or use Dialogue
if show_notif: Rectangle {
@@ -190,7 +210,7 @@ export component MainWindow inherits Window {
y: 0px;
width: root.width;
height: root.height;
//padding only has effect on layout elements
//padding: 10px;

View File

@@ -0,0 +1,102 @@
import { Palette, TabWidget, Button, CheckBox } from "std-widgets.slint";
import { Graph, Node } from "../widgets/graph.slint";
import { SystemToggle } from "../widgets/common.slint";
import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint";
export global GPUPageData {
// GPU mode and device state
in-out property <int> gpu_mux_mode: 1; // 0 = Ultra/Discreet, 1 = Integrated/Optimus
in-out property <int> dgpu_disabled: 0; // 1 == dGPU disabled
in-out property <int> egpu_enabled: 0; // 1 == eGPU (XGMobile) enabled
callback cb_gpu_mux_mode(int);
callback cb_dgpu_disabled(int);
callback cb_egpu_enabled(int);
}
export component PageGPU inherits Rectangle {
clip: true;
ScrollView {
VerticalLayout {
padding: 10px;
spacing: 10px;
alignment: LayoutAlignment.start;
Rectangle {
background: Palette.alternate-background;
border-color: Palette.accent-background;
border-width: 3px;
border-radius: 10px;
height: 40px;
Text {
font-size: 18px;
color: Palette.control-foreground;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("GPU Configuration");
}
}
}
GroupBox {
HorizontalLayout {
spacing: 10px;
// Ultra (discreet) mode button - disabled if dGPU is marked disabled
Rectangle {
width: 120px;
height: 36px;
border-radius: 6px;
border-color: Palette.border;
border-width: 2px;
background: GPUPageData.gpu_mux_mode == 0 ? Palette.accent-background : Palette.control-background;
opacity: GPUPageData.dgpu_disabled == 1 ? 0.5 : 1.0;
Text {
color: Palette.control-foreground;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Ultra");
}
TouchArea {
width: 100%;
height: 100%;
clicked => {
if (GPUPageData.dgpu_disabled != 1 && GPUPageData.gpu_mux_mode != 0) {
GPUPageData.cb_gpu_mux_mode(0);
}
}
}
}
// Integrated (Optimus) mode button
Rectangle {
width: 120px;
height: 36px;
border-radius: 6px;
border-color: Palette.border;
border-width: 2px;
background: GPUPageData.gpu_mux_mode == 1 ? Palette.accent-background : Palette.control-background;
Text {
color: Palette.control-foreground;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Integrated");
}
TouchArea {
width: 100%;
height: 100%;
clicked => {
if (GPUPageData.gpu_mux_mode != 1) {
GPUPageData.cb_gpu_mux_mode(1);
}
}
}
}
}
}
}
}

View File

@@ -253,6 +253,66 @@ export component PageSystem inherits Rectangle {
}
}
if SystemPageData.kbd_leds_awake != -1 ||
SystemPageData.kbd_leds_sleep != -1 ||
SystemPageData.kbd_leds_boot != -1 ||
SystemPageData.kbd_leds_shutdown != -1: VerticalLayout {
padding: 0px;
spacing: 0px;
alignment: LayoutAlignment.start;
Rectangle {
background: Palette.alternate-background;
border-color: Palette.accent-background;
border-width: 3px;
border-radius: 10px;
height: 40px;
Text {
font-size: 18px;
color: Palette.control-foreground;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Keyboard Power Management");
}
}
GroupBox {
HorizontalLayout {
spacing: 10px;
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
text: @tr("Keyboard Awake Effect");
checked_int <=> SystemPageData.kbd_leds_awake;
toggled => {
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
}
}
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
text: @tr("Keyboard Sleep Effect");
checked_int <=> SystemPageData.kbd_leds_sleep;
toggled => {
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
}
}
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
text: @tr("Keyboard Boot Effect");
checked_int <=> SystemPageData.kbd_leds_boot;
toggled => {
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
}
}
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
text: @tr("Keyboard Shutdown Effect");
checked_int <=> SystemPageData.kbd_leds_shutdown;
toggled => {
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
}
}
}
}
}
Rectangle {
background: Palette.alternate-background;
border-color: Palette.accent-background;
@@ -286,44 +346,6 @@ export component PageSystem inherits Rectangle {
}
}
GroupBox {
title: @tr("Keyboard Power Management");
HorizontalLayout {
spacing: 10px;
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
text: @tr("Keyboard Awake Effect");
checked_int <=> SystemPageData.kbd_leds_awake;
toggled => {
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
}
}
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
text: @tr("Keyboard Sleep Effect");
checked_int <=> SystemPageData.kbd_leds_sleep;
toggled => {
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
}
}
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
text: @tr("Keyboard Boot Effect");
checked_int <=> SystemPageData.kbd_leds_boot;
toggled => {
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
}
}
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
text: @tr("Keyboard Shutdown Effect");
checked_int <=> SystemPageData.kbd_leds_shutdown;
toggled => {
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
}
}
}
}
HorizontalBox {
padding: 0px;
spacing: 10px;

View File

@@ -5,7 +5,7 @@ use zbus::proxy;
#[proxy(
interface = "xyz.ljones.Anime",
default_service = "xyz.ljones.Asusd",
default_path = "/xyz/ljones"
default_path = "/xyz/ljones/aura/anime"
)]
pub trait Anime {
/// DeviceState method

View File

@@ -253,8 +253,19 @@ impl FirmwareAttributes {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum FirmwareAttributeType {
#[default]
Immediate,
TUFKeyboard,
Ppt,
Gpu,
Bios,
}
macro_rules! define_attribute_getters {
($($attr:ident),*) => {
// Accept a list of attribute idents and an optional `types { .. }` block
( $( $attr:ident ),* $(,)? $( ; types { $( $tattr:ident : $ptype:ident ),* $(,)? } )? ) => {
impl FirmwareAttributes {
$(
pub fn $attr(&self) -> Option<&Attribute> {
@@ -268,6 +279,17 @@ macro_rules! define_attribute_getters {
});
)*
}
impl FirmwareAttribute {
pub fn property_type(&self) -> FirmwareAttributeType {
match <&str>::from(*self) {
$(
$( stringify!($tattr) => FirmwareAttributeType::$ptype, )*
)?
_ => FirmwareAttributeType::Immediate,
}
}
}
}
}
@@ -299,6 +321,38 @@ define_attribute_getters!(
gpu_mux_mode,
mini_led_mode,
screen_auto_brightness
; types {
ppt_pl1_spl: Ppt,
ppt_pl2_sppt: Ppt,
ppt_apu_sppt: Ppt,
ppt_platform_sppt: Ppt,
ppt_fppt: Ppt,
nv_dynamic_boost: Ppt,
nv_temp_target: Ppt,
dgpu_base_tgp: Ppt,
dgpu_tgp: Ppt,
gpu_mux_mode: Gpu,
egpu_connected: Gpu,
egpu_enable: Gpu,
dgpu_disable: Gpu,
boot_sound: Bios,
mcu_powersave: Immediate,
screen_auto_brightness: Immediate,
mini_led_mode: Immediate,
panel_hd_mode: Immediate,
panel_od: Immediate,
kbd_leds_awake: TUFKeyboard,
kbd_leds_sleep: TUFKeyboard,
kbd_leds_boot: TUFKeyboard,
kbd_leds_shutdown: TUFKeyboard,
charge_mode: Immediate,
}
);
/// CamelCase names of the properties. Intended for use with DBUS
@@ -352,29 +406,6 @@ pub enum FirmwareAttribute {
KbdLedsShutdown = 30,
}
impl FirmwareAttribute {
pub fn is_ppt(&self) -> bool {
matches!(
self,
FirmwareAttribute::PptPl1Spl
| FirmwareAttribute::PptPl2Sppt
| FirmwareAttribute::PptPl3Fppt
| FirmwareAttribute::PptFppt
| FirmwareAttribute::PptApuSppt
| FirmwareAttribute::PptPlatformSppt
)
}
pub fn is_dgpu(&self) -> bool {
matches!(
self,
FirmwareAttribute::NvDynamicBoost
| FirmwareAttribute::NvTempTarget
| FirmwareAttribute::DgpuTgp
)
}
}
impl From<&str> for FirmwareAttribute {
fn from(s: &str) -> Self {
match s {

1
rust-toolchain Normal file
View File

@@ -0,0 +1 @@
stable

View File

@@ -0,0 +1,70 @@
use super::Row;
// TODO: This is a placeholder for G635L map
pub const G635L: [Row; 63] = [
Row(0x01, 7, 32, 0),
Row(0x01, 7 + 34, 32, 0),
Row(0x01, 7 + 68, 32, 0),
Row(0x01, 7 + 102, 32, 0), // 34 len
Row(0x01, 7 + 136, 32, 0),
Row(0x01, 7 + 170, 34, 0),
Row(0x01, 7 + 204, 34, 0),
Row(0x01, 7 + 238, 34, 0),
Row(0x01, 7 + 272, 34, 0),
Row(0x01, 7 + 306, 34, 0),
Row(0x01, 7 + 340, 34, 0),
Row(0x01, 7 + 374, 34, 0),
Row(0x01, 7 + 408, 33, 1),
Row(0x01, 7 + 441, 33, 1),
Row(0x01, 7 + 474, 32, 2),
Row(0x01, 7 + 506, 32, 2),
Row(0x01, 7 + 538, 31, 3),
Row(0x01, 7 + 569, 31, 3),
Row(0x01, 7 + 600, 28, 4),
//
Row(0x74, 7 + 1, 3, 28 + 4), // adds to end of previous
Row(0x74, 7 + 3, 30, 4),
Row(0x74, 7 + 33, 29, 5),
Row(0x74, 7 + 62, 29, 5),
Row(0x74, 7 + 91, 28, 6),
Row(0x74, 7 + 119, 28, 6),
Row(0x74, 7 + 147, 27, 7),
Row(0x74, 7 + 174, 27, 7),
Row(0x74, 7 + 202, 26, 9),
Row(0x74, 7 + 228, 26, 9),
Row(0x74, 7 + 254, 25, 10),
Row(0x74, 7 + 278, 25, 9), // WEIRD OFFSET
Row(0x74, 7 + 303, 24, 10),
Row(0x74, 7 + 327, 24, 10),
Row(0x74, 7 + 351, 23, 11),
Row(0x74, 7 + 374, 23, 11),
Row(0x74, 7 + 397, 22, 12),
Row(0x74, 7 + 419, 22, 12),
Row(0x74, 7 + 441, 21, 13),
Row(0x74, 7 + 462, 21, 13),
Row(0x74, 7 + 483, 20, 14),
Row(0x74, 7 + 503, 20, 14),
Row(0x74, 7 + 523, 19, 15),
Row(0x74, 7 + 542, 19, 15),
Row(0x74, 7 + 561, 18, 16),
Row(0x74, 7 + 579, 18, 16),
Row(0x74, 7 + 597, 17, 17),
Row(0x74, 7 + 614, 13, 17),
//
Row(0xe7, 7 + 1, 4, 13 + 18), // adds to end of previous
Row(0xe7, 7 + 4, 16, 18),
Row(0xe7, 7 + 20, 16, 18),
Row(0xe7, 7 + 36, 15, 19),
Row(0xe7, 7 + 51, 15, 19),
Row(0xe7, 7 + 66, 14, 20),
Row(0xe7, 7 + 80, 12, 20), // too long? 14
Row(0xe7, 7 + 94, 13, 21),
Row(0xe7, 7 + 107, 13, 21),
Row(0xe7, 7 + 120, 12, 12), // Actual display end
Row(0xe7, 7 + 132, 12, 22),
Row(0xe7, 7 + 144, 11, 23),
Row(0xe7, 7 + 155, 11, 23),
Row(0xe7, 7 + 166, 10, 24),
Row(0xe7, 7 + 176, 10, 24),
Row(0xe7, 7 + 186, 9, 25),
];

View File

@@ -0,0 +1,70 @@
use super::Row;
// TODO: This is a placeholder for G835L map
pub const G835L: [Row; 63] = [
Row(0x01, 7, 32, 0),
Row(0x01, 7 + 34, 32, 0),
Row(0x01, 7 + 68, 32, 0),
Row(0x01, 7 + 102, 32, 0), // 34 len
Row(0x01, 7 + 136, 32, 0),
Row(0x01, 7 + 170, 34, 0),
Row(0x01, 7 + 204, 34, 0),
Row(0x01, 7 + 238, 34, 0),
Row(0x01, 7 + 272, 34, 0),
Row(0x01, 7 + 306, 34, 0),
Row(0x01, 7 + 340, 34, 0),
Row(0x01, 7 + 374, 34, 0),
Row(0x01, 7 + 408, 33, 1),
Row(0x01, 7 + 441, 33, 1),
Row(0x01, 7 + 474, 32, 2),
Row(0x01, 7 + 506, 32, 2),
Row(0x01, 7 + 538, 31, 3),
Row(0x01, 7 + 569, 31, 3),
Row(0x01, 7 + 600, 28, 4),
//
Row(0x74, 7 + 1, 3, 28 + 4), // adds to end of previous
Row(0x74, 7 + 3, 30, 4),
Row(0x74, 7 + 33, 29, 5),
Row(0x74, 7 + 62, 29, 5),
Row(0x74, 7 + 91, 28, 6),
Row(0x74, 7 + 119, 28, 6),
Row(0x74, 7 + 147, 27, 7),
Row(0x74, 7 + 174, 27, 7),
Row(0x74, 7 + 202, 26, 9),
Row(0x74, 7 + 228, 26, 9),
Row(0x74, 7 + 254, 25, 10),
Row(0x74, 7 + 278, 25, 9), // WEIRD OFFSET
Row(0x74, 7 + 303, 24, 10),
Row(0x74, 7 + 327, 24, 10),
Row(0x74, 7 + 351, 23, 11),
Row(0x74, 7 + 374, 23, 11),
Row(0x74, 7 + 397, 22, 12),
Row(0x74, 7 + 419, 22, 12),
Row(0x74, 7 + 441, 21, 13),
Row(0x74, 7 + 462, 21, 13),
Row(0x74, 7 + 483, 20, 14),
Row(0x74, 7 + 503, 20, 14),
Row(0x74, 7 + 523, 19, 15),
Row(0x74, 7 + 542, 19, 15),
Row(0x74, 7 + 561, 18, 16),
Row(0x74, 7 + 579, 18, 16),
Row(0x74, 7 + 597, 17, 17),
Row(0x74, 7 + 614, 13, 17),
//
Row(0xe7, 7 + 1, 4, 13 + 18), // adds to end of previous
Row(0xe7, 7 + 4, 16, 18),
Row(0xe7, 7 + 20, 16, 18),
Row(0xe7, 7 + 36, 15, 19),
Row(0xe7, 7 + 51, 15, 19),
Row(0xe7, 7 + 66, 14, 20),
Row(0xe7, 7 + 80, 12, 20), // too long? 14
Row(0xe7, 7 + 94, 13, 21),
Row(0xe7, 7 + 107, 13, 21),
Row(0xe7, 7 + 120, 12, 12), // Actual display end
Row(0xe7, 7 + 132, 12, 22),
Row(0xe7, 7 + 144, 11, 23),
Row(0xe7, 7 + 155, 11, 23),
Row(0xe7, 7 + 166, 10, 24),
Row(0xe7, 7 + 176, 10, 24),
Row(0xe7, 7 + 186, 9, 25),
];

View File

@@ -1,9 +1,13 @@
use rog_anime::AnimeType;
use self::map_g635l::G635L;
use self::map_g835l::G835L;
use self::map_ga401::GA401;
use self::map_ga402::GA402;
use self::map_gu604::GU604;
mod map_g635l;
mod map_g835l;
mod map_ga401;
mod map_ga402;
mod map_gu604;
@@ -39,6 +43,8 @@ pub struct AniMatrix {
impl AniMatrix {
pub fn new(model: AnimeType) -> Self {
let led_shape = match model {
// TODO: Verify how this reacts on G635L and G835L
// These are all doing the same thing. Can be simplified
AnimeType::GA401 => LedShape {
vertical: 2,
horizontal: 5,
@@ -58,10 +64,10 @@ impl AniMatrix {
// Do a hard mapping of each (derived from wireshardk captures)
let rows = match model {
AnimeType::GA401 => GA401.to_vec(),
AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => {
GA402.to_vec()
}
AnimeType::GA402 | AnimeType::Unsupported => GA402.to_vec(),
AnimeType::GU604 => GU604.to_vec(),
AnimeType::G635L => G635L.to_vec(),
AnimeType::G835L => G835L.to_vec(),
};
Self { rows, led_shape }