mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 17:33:19 +01:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49234af08b | ||
|
|
8f5717def8 | ||
|
|
9e55c0b2ca | ||
|
|
dd6ee91364 | ||
|
|
efbb838ca1 | ||
|
|
daf7d39d41 | ||
|
|
28b1194924 | ||
|
|
73d95ca187 | ||
|
|
00b7c6482f | ||
|
|
29c26e8c89 | ||
|
|
fb124dd228 | ||
|
|
0599be02dc | ||
|
|
81a88263a9 | ||
|
|
cea1fd2540 | ||
|
|
f2ced3bc7c | ||
|
|
dc2a05894b | ||
|
|
9ee962ad09 | ||
|
|
eb7ef0af4f | ||
|
|
dc51120c27 | ||
|
|
fc4c2c4346 | ||
|
|
3f6be037c1 | ||
|
|
0a80c97f02 | ||
|
|
88abafc728 | ||
|
|
ac880a0363 | ||
|
|
baebd51d99 | ||
|
|
226620eb53 | ||
|
|
1b34079d14 | ||
|
|
8deeffcdad | ||
|
|
b7e45d7305 | ||
|
|
d9077db234 | ||
|
|
439b006342 | ||
|
|
ffa74d52e5 | ||
|
|
6ccdd703e6 | ||
|
|
bb910344b8 | ||
|
|
b9c4ff9ca7 | ||
|
|
62a18d4e57 | ||
|
|
f520e381a9 | ||
|
|
1dd543ddf3 | ||
|
|
a7ef63bd8a | ||
|
|
db43c0f2a4 | ||
|
|
f0e5bb4ad1 |
29
CHANGELOG.md
29
CHANGELOG.md
@@ -6,6 +6,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
# [3.7.2] - 2021-08-02
|
||||
### Added
|
||||
- Enable multizone support on Strix 513IH
|
||||
- Add G513QY ledmodes
|
||||
### Changed
|
||||
- Fix missing CLI command help for some supported options
|
||||
- Fix incorrectly selecting profile by name, where the active profile was being copied to the selected profile
|
||||
- Add `asusd` version back to `asusctl -v` report
|
||||
- Fix various clippy warnings
|
||||
|
||||
# [3.7.1] - 2021-06-11
|
||||
### Changed
|
||||
- Refine graphics mode switching:
|
||||
+ Disallow switching to compute or vfio mode unless existing mode is "Integrated"
|
||||
|
||||
# [3.7.0] - 2021-06-06
|
||||
### Changed
|
||||
- Set PM to auto for Nvidia always
|
||||
- Extra info output for gfx dev scan
|
||||
- Extra info in log for G-Sync to help prevent user confusion around gfx switching
|
||||
- Add GA503Q led modes
|
||||
- Added ability to fade in/out gifs and images for anime. This does break anime configs. See manual for details.
|
||||
- Added task to CtrlLed to set the keyboard LED brightness on wake from suspend
|
||||
+ requires a kernel patch which will be upstreamed and in fedora rog kernel
|
||||
- Make gfx change from nvidia to vfio/compute also force-change to integrated _then_
|
||||
to requested mode
|
||||
- Fix invalid gfx status when switching from some modes
|
||||
- Fix copy over of serde skipped config values on config reload
|
||||
|
||||
# [3.6.1] - 2021-05-25
|
||||
### Changed
|
||||
- Bugfix: write correct fan modes for profiles
|
||||
|
||||
241
Cargo.lock
generated
241
Cargo.lock
generated
@@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -31,10 +31,10 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "asus-notify"
|
||||
version = "3.0.0"
|
||||
version = "3.0.1"
|
||||
dependencies = [
|
||||
"daemon",
|
||||
"notify-rust",
|
||||
"rog_aura",
|
||||
"rog_dbus",
|
||||
"rog_profiles",
|
||||
"rog_types",
|
||||
@@ -43,8 +43,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusctl"
|
||||
version = "3.5.0"
|
||||
version = "3.5.1"
|
||||
dependencies = [
|
||||
"daemon",
|
||||
"gif",
|
||||
"glam",
|
||||
"gumdrop",
|
||||
@@ -60,20 +61,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "1.3.1"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd"
|
||||
checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-lite",
|
||||
"libc",
|
||||
"log",
|
||||
"nb-connect",
|
||||
"once_cell",
|
||||
"parking",
|
||||
"polling",
|
||||
"vec-arena",
|
||||
"slab",
|
||||
"socket2",
|
||||
"waker-fn",
|
||||
"winapi",
|
||||
]
|
||||
@@ -144,9 +145,9 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.67"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -196,18 +197,17 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.3"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "daemon"
|
||||
version = "3.6.2"
|
||||
version = "3.7.2"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
@@ -232,9 +232,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "daemon-user"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
dependencies = [
|
||||
"dirs 3.0.1",
|
||||
"dirs 3.0.2",
|
||||
"rog_anime",
|
||||
"rog_dbus",
|
||||
"rog_types",
|
||||
@@ -254,7 +254,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -264,27 +264,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"redox_users 0.3.5",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff"
|
||||
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
|
||||
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"redox_users 0.4.0",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -306,7 +306,7 @@ checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -324,18 +324,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3"
|
||||
checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
|
||||
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -348,9 +348,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
|
||||
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -358,15 +358,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
|
||||
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
|
||||
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@@ -375,15 +375,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
|
||||
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.11.3"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb"
|
||||
checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
@@ -396,34 +396,36 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
|
||||
checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
|
||||
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
|
||||
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
|
||||
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@@ -449,6 +451,17 @@ dependencies = [
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.2"
|
||||
@@ -485,7 +498,7 @@ checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -536,9 +549,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.93"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
||||
|
||||
[[package]]
|
||||
name = "libudev-sys"
|
||||
@@ -608,9 +621,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
@@ -624,9 +637,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nb-connect"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19900e7eee95eb2b3c2e26d12a874cc80aaf750e31be6fcbe743ead369fa45d"
|
||||
checksum = "b1bb540dc6ef51cfe1916ec038ce7a620daf3a111e2502d745197cd53d6bca15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"socket2",
|
||||
@@ -657,9 +670,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "notify-rust"
|
||||
version = "4.3.0"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00c16afe17474a42a59062f3409a63160c63d41985b25e9e613400685b839cb6"
|
||||
checksum = "2a2ca742cd7268b60c35828d318357f0b1bb9b82088e157ccf3013eb3ce70247"
|
||||
dependencies = [
|
||||
"mac-notification-sys",
|
||||
"serde",
|
||||
@@ -761,9 +774,9 @@ checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "png_pong"
|
||||
version = "0.8.0"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75851150081bd473079e03e2fa00e25557bcb19706e502b095ca71ce392b70ff"
|
||||
checksum = "32b76c1da19406fed18e81972b9015a775447532647b04a8949135916d67778f"
|
||||
dependencies = [
|
||||
"miniz_oxide",
|
||||
"pix",
|
||||
@@ -805,11 +818,11 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.26"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -833,22 +846,41 @@ version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"getrandom 0.1.16",
|
||||
"redox_syscall 0.1.57",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.5"
|
||||
name = "redox_users"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom 0.2.3",
|
||||
"redox_syscall 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -857,13 +889,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.23"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rog_anime"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
dependencies = [
|
||||
"gif",
|
||||
"glam",
|
||||
@@ -887,7 +919,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_dbus"
|
||||
version = "3.4.0"
|
||||
version = "3.5.1"
|
||||
dependencies = [
|
||||
"rog_anime",
|
||||
"rog_aura",
|
||||
@@ -909,7 +941,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_profiles"
|
||||
version = "0.1.0"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"intel-pstate",
|
||||
"rog_fan_curve",
|
||||
@@ -932,9 +964,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rusb"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12f3264859095257507e4c011ab420ff9b2d9cc3349c6c08a1d3a019260bb437"
|
||||
checksum = "d9a5084628cc5be77b1c750b3e5ee0cc519d2f2491b3f06b78b3aac3328b00ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libusb1-sys",
|
||||
@@ -966,22 +998,22 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -997,20 +1029,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
|
||||
checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
|
||||
|
||||
[[package]]
|
||||
name = "smart-default"
|
||||
@@ -1020,7 +1052,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1062,13 +1094,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.69"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1115,17 +1147,16 @@ checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -1166,21 +1197,15 @@ checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.11"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||
|
||||
[[package]]
|
||||
name = "vec-arena"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34b2f665b594b07095e3ac3f718e13c2197143416fae4c5706cffb7b1af8d7f1"
|
||||
checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
@@ -1208,15 +1233,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
|
||||
checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
|
||||
|
||||
[[package]]
|
||||
name = "wepoll-sys"
|
||||
@@ -1330,7 +1355,7 @@ dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1354,5 +1379,5 @@ dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.69",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
22
MANUAL.md
22
MANUAL.md
@@ -269,6 +269,7 @@ Each object in the array can be one of:
|
||||
<FLOAT>,
|
||||
<FLOAT>
|
||||
],
|
||||
"time": <TIME>,
|
||||
"brightness": <FLOAT>
|
||||
}
|
||||
},
|
||||
@@ -322,6 +323,27 @@ A cycle is how many gif loops to run:
|
||||
```json
|
||||
"time": "Infinite",
|
||||
```
|
||||
`Fade` allows an image or gif to fade in and out, and remain at max brightness to n time:
|
||||
```json
|
||||
"time": {
|
||||
"Fade": {
|
||||
"fade_in": {
|
||||
"secs": 2,
|
||||
"nanos": 0
|
||||
},
|
||||
"show_for": {
|
||||
"secs": 1,
|
||||
"nanos": 0
|
||||
},
|
||||
"fade_out": {
|
||||
"secs": 2,
|
||||
"nanos": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
`show_for` can be `null`, if it is `null` then the `show_for` becomes `gif_time_length - fade_in - fade_out`.
|
||||
This is period for which the gif or image will be max brightness (as set).
|
||||
|
||||
**<INT>**
|
||||
|
||||
|
||||
13
Makefile
13
Makefile
@@ -56,6 +56,13 @@ install:
|
||||
$(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png"
|
||||
$(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png"
|
||||
$(INSTALL_DATA) "./data/icons/asus_notif_red.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_red.png"
|
||||
|
||||
$(INSTALL_DATA) "./data/icons/scalable/gpu-compute.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-compute.svg"
|
||||
$(INSTALL_DATA) "./data/icons/scalable/gpu-hybrid.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-hybrid.svg"
|
||||
$(INSTALL_DATA) "./data/icons/scalable/gpu-integrated.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-integrated.svg"
|
||||
$(INSTALL_DATA) "./data/icons/scalable/gpu-nvidia.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-nvidia.svg"
|
||||
$(INSTALL_DATA) "./data/icons/scalable/gpu-vfio.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg"
|
||||
$(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
|
||||
$(INSTALL_DATA) "./data/_asusctl" "$(DESTDIR)$(zshcpl)/_asusctl"
|
||||
$(INSTALL_DATA) "./data/completions/asusctl.fish" "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish"
|
||||
cd data && find "./anime" -type f -exec install -Dm 755 "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
||||
@@ -74,6 +81,12 @@ uninstall:
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_red.png"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-compute.svg"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-hybrid.svg"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-integrated.svg"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-nvidia.svg"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg"
|
||||
rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
|
||||
rm -f "$(DESTDIR)$(zshcpl)/_asusctl"
|
||||
rm -f "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish"
|
||||
rm -rf "$(DESTDIR)$(datarootdir)/asusd"
|
||||
|
||||
@@ -25,7 +25,7 @@ Various patches are required for keyboard support. See [this post](https://asus-
|
||||
|
||||
## Discord
|
||||
|
||||
[Discord server link](https://discord.gg/ngbdKabAnP)
|
||||
[Discord server link](https://discord.gg/4ZKGd7Un5t)
|
||||
|
||||
## SUPPORTED LAPTOPS
|
||||
|
||||
@@ -111,4 +111,4 @@ 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.
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "asus-notify"
|
||||
version = "3.0.0"
|
||||
version = "3.0.1"
|
||||
authors = ["Luke D Jones <luke@ljones.dev>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -10,9 +10,9 @@ edition = "2018"
|
||||
# serialisation
|
||||
serde_json = "^1.0"
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
rog_aura = { path = "../rog-aura" }
|
||||
rog_types = { path = "../rog-types" }
|
||||
daemon = { path = "../daemon" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
|
||||
[dependencies.notify-rust]
|
||||
version = "^4.3"
|
||||
|
||||
@@ -1,22 +1,45 @@
|
||||
use notify_rust::{Hint, Notification, NotificationHandle};
|
||||
use rog_aura::AuraEffect;
|
||||
use rog_dbus::{DbusProxies, Signals};
|
||||
use rog_profiles::profiles::{FanLevel, Profile};
|
||||
use rog_types::gfx_vendors::GfxRequiredUserAction;
|
||||
use rog_types::gfx_vendors::GfxVendors;
|
||||
use std::error::Error;
|
||||
use std::process;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
const NOTIF_HEADER: &str = "ROG Control";
|
||||
|
||||
macro_rules! notify {
|
||||
($notifier:ident, $last_notif:ident, $data:expr) => {
|
||||
if let Some(notif) = $last_notif.take() {
|
||||
notif.close();
|
||||
}
|
||||
if let Ok(x) = $notifier($data) {
|
||||
$last_notif = Some(x);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! base_notification {
|
||||
($body:expr) => {
|
||||
Notification::new()
|
||||
.summary(NOTIF_HEADER)
|
||||
.body($body)
|
||||
.timeout(2000)
|
||||
.show()
|
||||
};
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("asus-notify version {}", env!("CARGO_PKG_VERSION"));
|
||||
println!(" daemon version {}", daemon::VERSION);
|
||||
println!(" rog-dbus version {}", rog_dbus::VERSION);
|
||||
|
||||
let (proxies, conn) = DbusProxies::new()?;
|
||||
let signals = Signals::new(&proxies)?;
|
||||
|
||||
let mut last_profile_notif: Option<NotificationHandle> = None;
|
||||
let mut last_led_notif: Option<NotificationHandle> = None;
|
||||
let mut last_gfx_notif: Option<NotificationHandle> = None;
|
||||
let mut last_chrg_notif: Option<NotificationHandle> = None;
|
||||
let mut last_notification: Option<NotificationHandle> = None;
|
||||
|
||||
let recv = proxies.setup_recv(conn);
|
||||
let mut err_count = 0;
|
||||
@@ -36,42 +59,30 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
err_count = 0;
|
||||
|
||||
if let Ok(vendor) = signals.gfx_vendor.try_recv() {
|
||||
if let Some(notif) = last_gfx_notif.take() {
|
||||
notif.close();
|
||||
}
|
||||
let x = do_notif(&format!(
|
||||
"Graphics mode changed to {}",
|
||||
<&str>::from(vendor)
|
||||
))?;
|
||||
last_gfx_notif = Some(x);
|
||||
if let Ok(data) = signals.led_mode.try_recv() {
|
||||
notify!(do_led_notif, last_notification, &data);
|
||||
}
|
||||
|
||||
if let Ok(limit) = signals.charge.try_recv() {
|
||||
if let Some(notif) = last_chrg_notif.take() {
|
||||
notif.close();
|
||||
}
|
||||
let x = do_notif(&format!("Battery charge limit changed to {}", limit))?;
|
||||
last_chrg_notif = Some(x);
|
||||
if let Ok(data) = signals.profile.try_recv() {
|
||||
notify!(do_thermal_notif, last_notification, &data);
|
||||
}
|
||||
|
||||
if let Ok(profile) = signals.profile.try_recv() {
|
||||
if let Some(notif) = last_profile_notif.take() {
|
||||
notif.close();
|
||||
}
|
||||
let x = do_thermal_notif(&profile)?;
|
||||
last_profile_notif = Some(x);
|
||||
if let Ok(data) = signals.charge.try_recv() {
|
||||
notify!(do_charge_notif, last_notification, &data);
|
||||
}
|
||||
|
||||
if let Ok(ledmode) = signals.led_mode.try_recv() {
|
||||
if let Some(notif) = last_led_notif.take() {
|
||||
notif.close();
|
||||
if let Ok(data) = signals.gfx_vendor.try_recv() {
|
||||
notify!(do_gfx_notif, last_notification, &data);
|
||||
}
|
||||
if let Ok(data) = signals.gfx_action.try_recv() {
|
||||
match data {
|
||||
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
||||
do_gfx_action_notif(&data)?;
|
||||
}
|
||||
GfxRequiredUserAction::Integrated => {
|
||||
base_notification!(
|
||||
"You must be in integrated mode first to switch to the requested mode"
|
||||
)?;
|
||||
}
|
||||
GfxRequiredUserAction::None => {}
|
||||
}
|
||||
let x = do_notif(&format!(
|
||||
"Keyboard LED mode changed to {}",
|
||||
ledmode.mode_name()
|
||||
))?;
|
||||
last_led_notif = Some(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,11 +111,62 @@ fn do_thermal_notif(profile: &Profile) -> Result<NotificationHandle, Box<dyn Err
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
fn do_notif(body: &str) -> Result<NotificationHandle, Box<dyn Error>> {
|
||||
let x = Notification::new()
|
||||
.summary("ASUS ROG")
|
||||
.body(body)
|
||||
.timeout(2000)
|
||||
.show()?;
|
||||
Ok(x)
|
||||
fn do_led_notif(ledmode: &AuraEffect) -> Result<NotificationHandle, notify_rust::error::Error> {
|
||||
base_notification!(&format!(
|
||||
"Keyboard LED mode changed to {}",
|
||||
ledmode.mode_name()
|
||||
))
|
||||
}
|
||||
|
||||
fn do_charge_notif(limit: &u8) -> Result<NotificationHandle, notify_rust::error::Error> {
|
||||
base_notification!(&format!("Battery charge limit changed to {}", limit))
|
||||
}
|
||||
|
||||
fn do_gfx_notif(vendor: &GfxVendors) -> Result<NotificationHandle, notify_rust::error::Error> {
|
||||
let icon = match vendor {
|
||||
GfxVendors::Nvidia => "/usr/share/icons/hicolor/scalable/status/gpu-nvidia.svg",
|
||||
GfxVendors::Integrated => "/usr/share/icons/hicolor/scalable/status/gpu-integrated.svg",
|
||||
GfxVendors::Compute => "/usr/share/icons/hicolor/scalable/status/gpu-compute.svg",
|
||||
GfxVendors::Vfio => "/usr/share/icons/hicolor/scalable/status/gpu-vfio.svg",
|
||||
GfxVendors::Hybrid => "/usr/share/icons/hicolor/scalable/status/gpu-hybrid.svg",
|
||||
};
|
||||
Notification::new()
|
||||
.summary(NOTIF_HEADER)
|
||||
.body(&format!(
|
||||
"Graphics mode changed to {}",
|
||||
<&str>::from(vendor)
|
||||
))
|
||||
.timeout(2000)
|
||||
.icon(icon)
|
||||
.show()
|
||||
}
|
||||
|
||||
fn do_gfx_action_notif(vendor: &GfxRequiredUserAction) -> Result<(), notify_rust::error::Error> {
|
||||
let mut notif = Notification::new()
|
||||
.summary(NOTIF_HEADER)
|
||||
.timeout(2000)
|
||||
.urgency(notify_rust::Urgency::Critical)
|
||||
.icon("/usr/share/icons/hicolor/scalable/status/notification-reboot.svg")
|
||||
.finalize();
|
||||
|
||||
if matches!(vendor, GfxRequiredUserAction::Logout) {
|
||||
notif.action("logout", "Logout now?");
|
||||
} else if matches!(vendor, GfxRequiredUserAction::Reboot) {
|
||||
notif.action("reboot", "Reboot now?");
|
||||
}
|
||||
|
||||
notif.body("Graphics mode changed");
|
||||
notif.show()?.wait_for_action(|action| match action {
|
||||
"logout" => {
|
||||
process::Command::new("gnome-session-quit").spawn().ok();
|
||||
}
|
||||
"reboot" => {
|
||||
process::Command::new("systemctl")
|
||||
.arg("reboot")
|
||||
.spawn()
|
||||
.ok();
|
||||
}
|
||||
_ => (),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "asusctl"
|
||||
version = "3.5.0"
|
||||
version = "3.5.1"
|
||||
authors = ["Luke D Jones <luke@ljones.dev>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -12,6 +12,7 @@ rog_aura = { path = "../rog-aura" }
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
rog_types = { path = "../rog-types" }
|
||||
daemon = { path = "../daemon" }
|
||||
rog_fan_curve = { version = "^0.1", features = ["serde"] }
|
||||
gumdrop = "^0.8"
|
||||
yansi-term = "^0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{env, path::Path, thread::sleep};
|
||||
|
||||
use rog_anime::{ActionData, AnimeAction, Sequences};
|
||||
use rog_anime::{ActionData, ActionLoader, Sequences};
|
||||
use rog_dbus::RogDbusClient;
|
||||
|
||||
fn main() {
|
||||
@@ -17,7 +17,7 @@ fn main() {
|
||||
let mut seq = Sequences::new();
|
||||
seq.insert(
|
||||
0,
|
||||
&AnimeAction::AsusAnimation {
|
||||
&ActionLoader::AsusAnimation {
|
||||
file: path.into(),
|
||||
time: rog_anime::AnimTime::Infinite,
|
||||
brightness,
|
||||
|
||||
@@ -124,6 +124,8 @@ pub struct MultiColourSpeed {
|
||||
/// Byte value for setting the built-in mode.
|
||||
///
|
||||
/// Enum corresponds to the required integer value
|
||||
///
|
||||
// NOTE: The option names here must match those in rog-aura crate
|
||||
#[derive(Options)]
|
||||
pub enum SetAuraBuiltin {
|
||||
#[options(help = "set a single static colour")]
|
||||
@@ -135,7 +137,7 @@ pub enum SetAuraBuiltin {
|
||||
#[options(help = "rainbow cycling in one of four directions")]
|
||||
Rainbow(SingleSpeedDirection),
|
||||
#[options(help = "rain pattern mimicking raindrops")]
|
||||
Star(TwoColourSpeed),
|
||||
Stars(TwoColourSpeed),
|
||||
#[options(help = "rain pattern of three preset colours")]
|
||||
Rain(SingleSpeed),
|
||||
#[options(help = "pressed keys are highlighted to fade")]
|
||||
@@ -233,7 +235,7 @@ impl From<&SetAuraBuiltin> for AuraEffect {
|
||||
data.mode = AuraModeNum::Rainbow;
|
||||
data
|
||||
}
|
||||
SetAuraBuiltin::Star(x) => {
|
||||
SetAuraBuiltin::Stars(x) => {
|
||||
let mut data: AuraEffect = x.into();
|
||||
data.mode = AuraModeNum::Star;
|
||||
data
|
||||
|
||||
@@ -11,10 +11,9 @@ use rog_aura::{self, AuraEffect};
|
||||
use rog_dbus::RogDbusClient;
|
||||
use rog_profiles::profiles::Profile;
|
||||
use rog_types::{
|
||||
gfx_vendors::GfxVendors,
|
||||
gfx_vendors::{GfxRequiredUserAction, GfxVendors},
|
||||
supported::{
|
||||
FanCpuSupportedFunctions, LedSupportedFunctions, RogBiosSupportedFunctions,
|
||||
SupportedFunctions,
|
||||
},
|
||||
};
|
||||
use std::{env::args, path::Path};
|
||||
@@ -133,16 +132,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let supported = dbus.proxies().supported().get_supported_functions()?;
|
||||
|
||||
if parsed.help {
|
||||
print_supported_help(&supported, &parsed);
|
||||
println!("\nSee https://asus-linux.org/faq/ for additional help");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if parsed.version {
|
||||
println!(" asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||
println!("rog-types v{}", rog_types::VERSION);
|
||||
println!("\nApp and daemon versions:");
|
||||
println!(" asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||
println!(" asusd v{}", daemon::VERSION);
|
||||
println!("\nComponent crate versions:");
|
||||
println!(" rog-anime v{}", rog_anime::VERSION);
|
||||
println!(" rog-aura v{}", rog_aura::VERSION);
|
||||
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||
println!("rog-profiles v{}", rog_profiles::VERSION);
|
||||
println!(" rog-types v{}", rog_types::VERSION);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -158,10 +157,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
}
|
||||
if let Some(anime_turn) = cmd.turn {
|
||||
dbus.proxies().anime().toggle_on(anime_turn.into())?
|
||||
dbus.proxies().anime().set_led_power(anime_turn.into())?
|
||||
}
|
||||
if let Some(anime_boot) = cmd.boot {
|
||||
dbus.proxies().anime().toggle_boot_on(anime_boot.into())?
|
||||
dbus.proxies()
|
||||
.anime()
|
||||
.set_system_animations(anime_boot.into())?
|
||||
}
|
||||
if let Some(action) = cmd.command {
|
||||
match action {
|
||||
@@ -222,8 +223,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
if parsed.show_supported {
|
||||
let dat = dbus.proxies().supported().get_supported_functions()?;
|
||||
println!("Supported laptop functions:\n{:?}", dat);
|
||||
println!("Supported laptop functions:\n\n{}", supported);
|
||||
}
|
||||
|
||||
if let Some(chg_limit) = parsed.chg_limit {
|
||||
@@ -233,57 +233,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_supported_help(supported: &SupportedFunctions, parsed: &CliStart) {
|
||||
// As help option don't work with `parse_args_default`
|
||||
// we will call `parse_args_default_or_exit` instead
|
||||
let usage: Vec<String> = parsed.self_usage().lines().map(|s| s.to_string()).collect();
|
||||
for line in usage.iter().filter(|line| {
|
||||
if line.contains("--fan-mode") && !supported.fan_cpu_ctrl.stock_fan_modes {
|
||||
return false;
|
||||
}
|
||||
if line.contains("--chg-limit") && !supported.charge_ctrl.charge_level_set {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}) {
|
||||
println!("{}", line);
|
||||
}
|
||||
|
||||
// command strings are in order of the struct
|
||||
let commands: Vec<String> = CliCommand::usage().lines().map(|s| s.to_string()).collect();
|
||||
println!("\nCommands available");
|
||||
for line in commands.iter().filter(|line| {
|
||||
if line.contains("profile")
|
||||
&& !supported.fan_cpu_ctrl.stock_fan_modes
|
||||
&& !supported.fan_cpu_ctrl.fan_curve_set
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if line.contains("led-mode") && !supported.keyboard_led.stock_led_modes.is_empty() {
|
||||
return false;
|
||||
}
|
||||
if line.contains("bios")
|
||||
&& (!supported.rog_bios_ctrl.dedicated_gfx_toggle
|
||||
|| !supported.rog_bios_ctrl.post_sound_toggle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if line.contains("anime") && !supported.anime_ctrl.0 {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}) {
|
||||
println!("{}", line);
|
||||
}
|
||||
|
||||
if !supported.fan_cpu_ctrl.stock_fan_modes {
|
||||
println!("Note: Fan mode control is not supported by this laptop");
|
||||
}
|
||||
if !supported.charge_ctrl.charge_level_set {
|
||||
println!("Note: Charge control is not supported by this laptop");
|
||||
}
|
||||
}
|
||||
|
||||
fn do_gfx(
|
||||
dbus: &RogDbusClient,
|
||||
supported: &RogBiosSupportedFunctions,
|
||||
@@ -307,11 +256,24 @@ fn do_gfx(
|
||||
err
|
||||
})?;
|
||||
let res = dbus.gfx_wait_changed()?;
|
||||
println!(
|
||||
"Graphics mode changed to {}. User action required is: {}",
|
||||
<&str>::from(mode),
|
||||
<&str>::from(&res)
|
||||
);
|
||||
match res {
|
||||
GfxRequiredUserAction::Integrated => {
|
||||
println!(
|
||||
"You must change to Integrated before you can change to {}",
|
||||
<&str>::from(mode)
|
||||
);
|
||||
}
|
||||
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
||||
println!(
|
||||
"Graphics mode changed to {}. User action required is: {}",
|
||||
<&str>::from(mode),
|
||||
<&str>::from(&res)
|
||||
);
|
||||
}
|
||||
GfxRequiredUserAction::None => {
|
||||
println!("Graphics mode changed to {}", <&str>::from(mode));
|
||||
}
|
||||
}
|
||||
std::process::exit(0)
|
||||
}
|
||||
if command.get {
|
||||
@@ -354,7 +316,7 @@ fn handle_led_mode(
|
||||
.collect();
|
||||
for command in commands.iter().filter(|command| {
|
||||
for mode in &supported.stock_led_modes {
|
||||
if command.contains(<&str>::from(mode)) {
|
||||
if command.contains(&<&str>::from(mode).to_lowercase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -479,12 +441,21 @@ fn handle_profile(
|
||||
}
|
||||
|
||||
let mut set_profile = false;
|
||||
let mut profile;
|
||||
let mut profile = Profile::default();
|
||||
if cmd.create {
|
||||
profile = Profile::default();
|
||||
set_profile = true;
|
||||
} else {
|
||||
profile = dbus.proxies().profile().active_data()?;
|
||||
} else if let Some(ref name) = cmd.profile {
|
||||
let profiles = dbus.proxies().profile().all_profile_data()?;
|
||||
for p in profiles {
|
||||
if p.name == *name {
|
||||
profile = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if profile.name != *name {
|
||||
println!("The requested profile doesn't exist, you may need to create it");
|
||||
std::process::exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(turbo) = cmd.turbo {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "daemon-user"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
authors = ["Luke D Jones <luke@ljones.dev>"]
|
||||
edition = "2018"
|
||||
description = "Usermode daemon for user settings, anime, per-key lighting"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use rog_anime::{ActionData, AnimTime, AnimeAction, Sequences, Vec2};
|
||||
use rog_anime::{ActionData, ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
||||
use rog_dbus::RogDbusClient;
|
||||
//use crate::dbus::DbusEvents;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
@@ -17,6 +16,44 @@ use zvariant_derive::Type;
|
||||
|
||||
use crate::{error::Error, user_config::UserAnimeConfig};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
|
||||
pub struct Timer {
|
||||
type_of: TimeType,
|
||||
/// If time type is Timer then this is milliseonds, otherwise it is animation loop count
|
||||
count: u64,
|
||||
/// Used only for `TimeType::Timer`, milliseonds to fade the image in for
|
||||
fade_in: Option<u64>,
|
||||
/// Used only for `TimeType::Timer`, milliseonds to fade the image out for
|
||||
fade_out: Option<u64>,
|
||||
}
|
||||
|
||||
impl From<Timer> for AnimTime {
|
||||
fn from(time: Timer) -> Self {
|
||||
match time.type_of {
|
||||
TimeType::Timer => {
|
||||
if time.fade_in.is_some() || time.fade_out.is_some() {
|
||||
let fade_in = time
|
||||
.fade_in
|
||||
.map_or(Duration::from_secs(0), Duration::from_millis);
|
||||
let fade_out = time
|
||||
.fade_out
|
||||
.map_or(Duration::from_secs(0), Duration::from_millis);
|
||||
let show_for = if time.count != 0 {
|
||||
Some(Duration::from_millis(time.count))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
AnimTime::Fade(Fade::new(fade_in, show_for, fade_out))
|
||||
} else {
|
||||
AnimTime::Time(Duration::from_millis(time.count))
|
||||
}
|
||||
}
|
||||
TimeType::Count => AnimTime::Count(time.count as u32),
|
||||
TimeType::Infinite => AnimTime::Infinite,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
|
||||
pub enum TimeType {
|
||||
Timer,
|
||||
@@ -29,14 +66,14 @@ pub enum TimeType {
|
||||
pub struct CtrlAnimeInner<'a> {
|
||||
sequences: Sequences,
|
||||
client: RogDbusClient<'a>,
|
||||
do_early_return: &'a AtomicBool,
|
||||
do_early_return: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl<'a> CtrlAnimeInner<'static> {
|
||||
pub fn new(
|
||||
sequences: Sequences,
|
||||
client: RogDbusClient<'static>,
|
||||
do_early_return: &'static AtomicBool,
|
||||
do_early_return: Arc<AtomicBool>,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
sequences,
|
||||
@@ -45,7 +82,7 @@ impl<'a> CtrlAnimeInner<'static> {
|
||||
})
|
||||
}
|
||||
/// To be called on each main loop iteration to pump out commands to the anime
|
||||
pub fn run(&self) -> Result<(), Error> {
|
||||
pub fn run(&'a self) -> Result<(), Error> {
|
||||
if self.do_early_return.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -53,32 +90,10 @@ impl<'a> CtrlAnimeInner<'static> {
|
||||
for action in self.sequences.iter() {
|
||||
match action {
|
||||
ActionData::Animation(frames) => {
|
||||
let mut count = 0;
|
||||
let start = Instant::now();
|
||||
'animation: loop {
|
||||
for frame in frames.frames() {
|
||||
if self.do_early_return.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
self.client
|
||||
.proxies()
|
||||
.anime()
|
||||
.write(frame.frame().clone())
|
||||
.unwrap();
|
||||
if let AnimTime::Time(time) = frames.duration() {
|
||||
if Instant::now().duration_since(start) > time {
|
||||
break 'animation;
|
||||
}
|
||||
}
|
||||
sleep(frame.delay());
|
||||
}
|
||||
if let AnimTime::Cycles(times) = frames.duration() {
|
||||
count += 1;
|
||||
if count >= times {
|
||||
break 'animation;
|
||||
}
|
||||
}
|
||||
}
|
||||
rog_anime::run_animation(frames, self.do_early_return.clone(), &|output| {
|
||||
self.client.proxies().anime().write(output).unwrap()
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
ActionData::Image(image) => {
|
||||
self.client
|
||||
@@ -115,7 +130,7 @@ pub struct CtrlAnime<'a> {
|
||||
client: RogDbusClient<'a>,
|
||||
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
||||
/// Must be the same Atomic as in CtrlAnimeInner
|
||||
inner_early_return: &'a AtomicBool,
|
||||
inner_early_return: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl<'a> CtrlAnime<'static> {
|
||||
@@ -123,7 +138,7 @@ impl<'a> CtrlAnime<'static> {
|
||||
config: Arc<Mutex<UserAnimeConfig>>,
|
||||
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
||||
client: RogDbusClient<'static>,
|
||||
inner_early_return: &'static AtomicBool,
|
||||
inner_early_return: Arc<AtomicBool>,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(CtrlAnime {
|
||||
config,
|
||||
@@ -159,18 +174,13 @@ impl CtrlAnime<'static> {
|
||||
&mut self,
|
||||
index: u32,
|
||||
file: String,
|
||||
time: TimeType,
|
||||
count: u32,
|
||||
time: Timer,
|
||||
brightness: f32,
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let time: AnimTime = match time {
|
||||
TimeType::Timer => AnimTime::Time(Duration::from_millis(count as u64)),
|
||||
TimeType::Count => AnimTime::Cycles(count),
|
||||
TimeType::Infinite => AnimTime::Infinite,
|
||||
};
|
||||
let time: AnimTime = time.into();
|
||||
let file = Path::new(&file);
|
||||
let action = AnimeAction::AsusAnimation {
|
||||
let action = ActionLoader::AsusAnimation {
|
||||
file: file.into(),
|
||||
brightness,
|
||||
time,
|
||||
@@ -205,19 +215,14 @@ impl CtrlAnime<'static> {
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
xy: (f32, f32),
|
||||
time: TimeType,
|
||||
count: u32,
|
||||
time: Timer,
|
||||
brightness: f32,
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let time: AnimTime = match time {
|
||||
TimeType::Timer => AnimTime::Time(Duration::from_millis(count as u64)),
|
||||
TimeType::Count => AnimTime::Cycles(count),
|
||||
TimeType::Infinite => AnimTime::Infinite,
|
||||
};
|
||||
let time: AnimTime = time.into();
|
||||
let file = Path::new(&file);
|
||||
let translation = Vec2::new(xy.0, xy.1);
|
||||
let action = AnimeAction::ImageAnimation {
|
||||
let action = ActionLoader::ImageAnimation {
|
||||
file: file.into(),
|
||||
scale,
|
||||
angle,
|
||||
@@ -248,6 +253,7 @@ impl CtrlAnime<'static> {
|
||||
Err(zbus::fdo::Error::Failed("UserConfig lock fail".into()))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn insert_image(
|
||||
&mut self,
|
||||
index: u32,
|
||||
@@ -255,16 +261,19 @@ impl CtrlAnime<'static> {
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
xy: (f32, f32),
|
||||
time: Option<Timer>,
|
||||
brightness: f32,
|
||||
) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let file = Path::new(&file);
|
||||
let action = AnimeAction::Image {
|
||||
let time = time.map(|time| time.into());
|
||||
let action = ActionLoader::Image {
|
||||
file: file.into(),
|
||||
scale,
|
||||
angle,
|
||||
translation: Vec2::new(xy.0, xy.1),
|
||||
brightness,
|
||||
time,
|
||||
};
|
||||
|
||||
// Must make the inner run loop return early
|
||||
@@ -291,7 +300,7 @@ impl CtrlAnime<'static> {
|
||||
|
||||
pub fn insert_pause(&mut self, index: u32, millis: u64) -> zbus::fdo::Result<String> {
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
let action = AnimeAction::Pause(Duration::from_millis(millis));
|
||||
let action = ActionLoader::Pause(Duration::from_millis(millis));
|
||||
// Must make the inner run loop return early
|
||||
self.inner_early_return.store(true, Ordering::SeqCst);
|
||||
|
||||
@@ -340,13 +349,13 @@ impl CtrlAnime<'static> {
|
||||
pub fn set_state(&mut self, on: bool) -> zbus::fdo::Result<()> {
|
||||
// Operations here need to be in specific order
|
||||
if on {
|
||||
self.client.proxies().anime().toggle_on(on)?;
|
||||
self.client.proxies().anime().set_led_power(on)?;
|
||||
// Let the inner loop run
|
||||
self.inner_early_return.store(false, Ordering::SeqCst);
|
||||
} else {
|
||||
// Must make the inner run loop return early
|
||||
self.inner_early_return.store(true, Ordering::SeqCst);
|
||||
self.client.proxies().anime().toggle_on(on)?;
|
||||
self.client.proxies().anime().set_led_power(on)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ use zbus::{fdo, Connection};
|
||||
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
/// The anime loop needs an atomic to make it exit early if required
|
||||
static ANIME_INNER_EARLY_RETURN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" user daemon v{}", rog_user::VERSION);
|
||||
println!(" rog-anime v{}", rog_anime::VERSION);
|
||||
@@ -39,20 +36,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Set up the anime data and run loop/thread
|
||||
if supported.anime_ctrl.0 {
|
||||
let early_return = Arc::new(AtomicBool::new(false));
|
||||
// Inner behind mutex required for thread safety
|
||||
let inner = Arc::new(Mutex::new(CtrlAnimeInner::new(
|
||||
anime,
|
||||
client,
|
||||
&ANIME_INNER_EARLY_RETURN,
|
||||
early_return.clone(),
|
||||
)?));
|
||||
// Need new client object for dbus control part
|
||||
let (client, _) = RogDbusClient::new().unwrap();
|
||||
let anime_control = CtrlAnime::new(
|
||||
anime_config,
|
||||
inner.clone(),
|
||||
client,
|
||||
&ANIME_INNER_EARLY_RETURN,
|
||||
)?;
|
||||
let anime_control = CtrlAnime::new(anime_config, inner.clone(), client, early_return)?;
|
||||
anime_control.add_to_server(&mut server);
|
||||
// Thread using inner
|
||||
let _anime_thread = thread::Builder::new()
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use rog_anime::{AnimTime, AnimeAction, Sequences, Vec2};
|
||||
use rog_anime::{ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use crate::error::Error;
|
||||
@@ -12,7 +12,7 @@ use crate::error::Error;
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct UserAnimeConfig {
|
||||
pub name: String,
|
||||
pub anime: Vec<AnimeAction>,
|
||||
pub anime: Vec<ActionLoader>,
|
||||
}
|
||||
|
||||
impl UserAnimeConfig {
|
||||
@@ -95,34 +95,47 @@ impl Default for UserAnimeConfig {
|
||||
Self {
|
||||
name: "default".to_string(),
|
||||
anime: vec![
|
||||
AnimeAction::AsusAnimation {
|
||||
ActionLoader::AsusAnimation {
|
||||
file: "/usr/share/asusd/anime/asus/rog/Sunset.gif".into(),
|
||||
brightness: 0.5,
|
||||
time: AnimTime::Cycles(1),
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(6),
|
||||
None,
|
||||
Duration::from_secs(3),
|
||||
)),
|
||||
},
|
||||
AnimeAction::ImageAnimation {
|
||||
ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||
scale: 0.9,
|
||||
angle: 0.65,
|
||||
translation: Vec2::default(),
|
||||
brightness: 0.5,
|
||||
time: AnimTime::Time(Duration::from_secs(5)),
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
},
|
||||
AnimeAction::Image {
|
||||
ActionLoader::Image {
|
||||
file: "/usr/share/asusd/anime/custom/rust.png".into(),
|
||||
scale: 1.0,
|
||||
angle: 0.0,
|
||||
translation: Vec2::default(),
|
||||
time: Some(AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(1)),
|
||||
Duration::from_secs(2),
|
||||
))),
|
||||
brightness: 0.6,
|
||||
},
|
||||
AnimeAction::Pause(Duration::from_secs(6)),
|
||||
AnimeAction::ImageAnimation {
|
||||
ActionLoader::Pause(Duration::from_secs(1)),
|
||||
ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||
scale: 0.9,
|
||||
angle: 0.0,
|
||||
translation: Vec2::new(3.0, 2.0),
|
||||
brightness: 0.5,
|
||||
time: AnimTime::Cycles(2),
|
||||
time: AnimTime::Count(2),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "daemon"
|
||||
version = "3.6.2"
|
||||
version = "3.7.2"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -59,7 +59,7 @@ impl Default for Config {
|
||||
"silent".into(),
|
||||
0,
|
||||
100,
|
||||
true,
|
||||
false,
|
||||
FanLevel::Silent,
|
||||
"".to_string(),
|
||||
),
|
||||
@@ -142,24 +142,16 @@ impl Config {
|
||||
if l == 0 {
|
||||
warn!("File is empty {}", CONFIG_PATH);
|
||||
} else {
|
||||
let x: Config = serde_json::from_str(&buf)
|
||||
let mut x: Config = serde_json::from_str(&buf)
|
||||
.unwrap_or_else(|_| panic!("Could not deserialise {}", CONFIG_PATH));
|
||||
// copy over serde skipped values
|
||||
x.gfx_tmp_mode = self.gfx_tmp_mode;
|
||||
x.curr_fan_mode = self.curr_fan_mode;
|
||||
*self = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_new() -> Result<Config, Box<dyn std::error::Error>> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&CONFIG_PATH)
|
||||
.unwrap_or_else(|err| panic!("Error reading {}: {}", CONFIG_PATH, err));
|
||||
let mut buf = String::new();
|
||||
file.read_to_string(&mut buf)?;
|
||||
let x: Config = serde_json::from_str(&buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
pub fn write(&self) {
|
||||
let mut file = File::create(CONFIG_PATH).expect("Couldn't overwrite config");
|
||||
let json = serde_json::to_string_pretty(self).expect("Parse config to JSON failed");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::VERSION;
|
||||
use log::{error, info, warn};
|
||||
use rog_anime::{error::AnimeError, ActionData, AnimTime, AnimeAction, Vec2};
|
||||
use rog_anime::Fade;
|
||||
use rog_anime::{error::AnimeError, ActionData, ActionLoader, AnimTime, Vec2};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
@@ -11,10 +12,10 @@ pub static ANIME_CACHE_PATH: &str = "/etc/asusd/anime-cache.conf";
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AnimeConfigV341 {
|
||||
pub system: Option<AnimeAction>,
|
||||
pub boot: Option<AnimeAction>,
|
||||
pub suspend: Option<AnimeAction>,
|
||||
pub shutdown: Option<AnimeAction>,
|
||||
pub system: Option<ActionLoader>,
|
||||
pub boot: Option<ActionLoader>,
|
||||
pub suspend: Option<ActionLoader>,
|
||||
pub shutdown: Option<ActionLoader>,
|
||||
}
|
||||
|
||||
impl AnimeConfigV341 {
|
||||
@@ -49,10 +50,10 @@ impl AnimeConfigV341 {
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AnimeConfigV352 {
|
||||
pub system: Vec<AnimeAction>,
|
||||
pub boot: Vec<AnimeAction>,
|
||||
pub wake: Vec<AnimeAction>,
|
||||
pub shutdown: Vec<AnimeAction>,
|
||||
pub system: Vec<ActionLoader>,
|
||||
pub boot: Vec<ActionLoader>,
|
||||
pub wake: Vec<ActionLoader>,
|
||||
pub shutdown: Vec<ActionLoader>,
|
||||
pub brightness: f32,
|
||||
}
|
||||
|
||||
@@ -110,10 +111,10 @@ impl AnimeConfigCached {
|
||||
/// Config for base system actions for the anime display
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AnimeConfig {
|
||||
pub system: Vec<AnimeAction>,
|
||||
pub boot: Vec<AnimeAction>,
|
||||
pub wake: Vec<AnimeAction>,
|
||||
pub shutdown: Vec<AnimeAction>,
|
||||
pub system: Vec<ActionLoader>,
|
||||
pub boot: Vec<ActionLoader>,
|
||||
pub wake: Vec<ActionLoader>,
|
||||
pub shutdown: Vec<ActionLoader>,
|
||||
pub brightness: f32,
|
||||
pub awake_enabled: bool,
|
||||
pub boot_anim_enabled: bool,
|
||||
@@ -165,8 +166,11 @@ impl AnimeConfig {
|
||||
info!("Updated config version to: {}", VERSION);
|
||||
return config;
|
||||
}
|
||||
warn!("Could not deserialise {}", ANIME_CONFIG_PATH);
|
||||
panic!("Please remove {} then restart asusd", ANIME_CONFIG_PATH);
|
||||
AnimeConfig::write_backup(buf);
|
||||
warn!(
|
||||
"Could not deserialise {}. Backed up as *-old",
|
||||
ANIME_CONFIG_PATH
|
||||
);
|
||||
}
|
||||
}
|
||||
AnimeConfig::create_default(&mut file)
|
||||
@@ -176,23 +180,31 @@ impl AnimeConfig {
|
||||
// create a default config here
|
||||
let config = AnimeConfig {
|
||||
system: vec![],
|
||||
boot: vec![AnimeAction::ImageAnimation {
|
||||
boot: vec![ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||
scale: 0.9,
|
||||
angle: 0.65,
|
||||
translation: Vec2::default(),
|
||||
brightness: 1.0,
|
||||
time: AnimTime::Time(Duration::from_secs(5)),
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
}],
|
||||
wake: vec![AnimeAction::ImageAnimation {
|
||||
wake: vec![ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||
scale: 0.9,
|
||||
angle: 0.65,
|
||||
translation: Vec2::default(),
|
||||
brightness: 1.0,
|
||||
time: AnimTime::Time(Duration::from_secs(5)),
|
||||
time: AnimTime::Fade(Fade::new(
|
||||
Duration::from_secs(2),
|
||||
Some(Duration::from_secs(2)),
|
||||
Duration::from_secs(2),
|
||||
)),
|
||||
}],
|
||||
shutdown: vec![AnimeAction::ImageAnimation {
|
||||
shutdown: vec![ActionLoader::ImageAnimation {
|
||||
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||
scale: 0.9,
|
||||
angle: 0.0,
|
||||
@@ -234,4 +246,12 @@ impl AnimeConfig {
|
||||
file.write_all(json.as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write config: {}", err));
|
||||
}
|
||||
|
||||
fn write_backup(buf: String) {
|
||||
let mut path = ANIME_CONFIG_PATH.to_string();
|
||||
path.push_str("-old");
|
||||
let mut file = File::create(&path).expect("Couldn't overwrite config");
|
||||
file.write_all(buf.as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write config: {}", err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ impl AuraConfig {
|
||||
let mut buf = String::new();
|
||||
if let Ok(read_len) = file.read_to_string(&mut buf) {
|
||||
if read_len == 0 {
|
||||
return AuraConfig::create_default(&mut file, &supported_led_modes);
|
||||
return AuraConfig::create_default(&mut file, supported_led_modes);
|
||||
} else {
|
||||
if let Ok(data) = serde_json::from_str(&buf) {
|
||||
return data;
|
||||
@@ -109,7 +109,7 @@ impl AuraConfig {
|
||||
panic!("Please remove {} then restart asusd", AURA_CONFIG_PATH);
|
||||
}
|
||||
}
|
||||
AuraConfig::create_default(&mut file, &supported_led_modes)
|
||||
AuraConfig::create_default(&mut file, supported_led_modes)
|
||||
}
|
||||
|
||||
fn create_default(file: &mut File, support_data: &LaptopLedData) -> Self {
|
||||
@@ -153,7 +153,7 @@ impl AuraConfig {
|
||||
.unwrap_or_else(|err| error!("Could not write config: {}", err));
|
||||
}
|
||||
|
||||
/// Multipurpose, will accecpt AuraEffect with zones and put in the correct store
|
||||
/// Multipurpose, will accept AuraEffect with zones and put in the correct store
|
||||
pub fn set_builtin(&mut self, effect: AuraEffect) {
|
||||
match effect.zone() {
|
||||
AuraZone::None => {
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::collections::BTreeMap;
|
||||
use crate::config::Config;
|
||||
|
||||
/// for parsing old v3.1.7 config
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct ConfigV317 {
|
||||
pub gfx_mode: GfxVendors,
|
||||
@@ -26,7 +27,7 @@ pub(crate) struct ConfigV317 {
|
||||
impl ConfigV317 {
|
||||
pub(crate) fn into_current(self) -> Config {
|
||||
Config {
|
||||
gfx_mode: GfxVendors::Hybrid,
|
||||
gfx_mode: self.gfx_mode,
|
||||
gfx_tmp_mode: None,
|
||||
gfx_managed: self.gfx_managed,
|
||||
gfx_vfio_enable: false,
|
||||
|
||||
@@ -5,7 +5,7 @@ use rog_anime::{
|
||||
pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on, pkts_for_init, PROD_ID,
|
||||
VENDOR_ID,
|
||||
},
|
||||
ActionData, AnimTime, AnimeDataBuffer, AnimePacketType, AnimePowerStates, ANIME_DATA_LEN,
|
||||
ActionData, AnimeDataBuffer, AnimePacketType, AnimePowerStates, ANIME_DATA_LEN,
|
||||
};
|
||||
use rog_types::supported::AnimeSupportedFunctions;
|
||||
use rusb::{Device, DeviceHandle};
|
||||
@@ -13,7 +13,6 @@ use std::{
|
||||
error::Error,
|
||||
sync::{Arc, Mutex},
|
||||
thread::sleep,
|
||||
time::Instant,
|
||||
};
|
||||
use std::{
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
@@ -144,31 +143,15 @@ impl CtrlAnime {
|
||||
for action in actions.iter() {
|
||||
match action {
|
||||
ActionData::Animation(frames) => {
|
||||
let mut count = 0;
|
||||
let start = Instant::now();
|
||||
'animation: loop {
|
||||
for frame in frames.frames() {
|
||||
if let Ok(lock) = inner.try_lock() {
|
||||
lock.write_data_buffer(frame.frame().clone());
|
||||
}
|
||||
if let AnimTime::Time(time) = frames.duration() {
|
||||
if Instant::now().duration_since(start) > time {
|
||||
break 'animation;
|
||||
}
|
||||
}
|
||||
sleep(frame.delay());
|
||||
// Need to check for early exit condition here or it might run
|
||||
// until end of gif or time
|
||||
if thread_exit.load(Ordering::SeqCst) {
|
||||
break 'main;
|
||||
}
|
||||
}
|
||||
if let AnimTime::Cycles(times) = frames.duration() {
|
||||
count += 1;
|
||||
if count >= times {
|
||||
break 'animation;
|
||||
}
|
||||
rog_anime::run_animation(frames, thread_exit.clone(), &|frame| {
|
||||
if let Ok(lock) = inner.try_lock() {
|
||||
lock.write_data_buffer(frame);
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
if thread_exit.load(Ordering::SeqCst) {
|
||||
break 'main;
|
||||
}
|
||||
}
|
||||
ActionData::Image(image) => {
|
||||
@@ -379,6 +362,7 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the global AniMe brightness
|
||||
fn set_brightness(&self, bright: f32) {
|
||||
'outer: loop {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
@@ -395,6 +379,7 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether the AniMe is displaying images/data
|
||||
fn set_on_off(&self, status: bool) {
|
||||
'outer: loop {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
@@ -413,6 +398,7 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether the AniMe will show boot, suspend, or off animations
|
||||
fn set_boot_on_off(&self, on: bool) {
|
||||
'outer: loop {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
@@ -446,6 +432,7 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get status of if the AniMe LEDs are on
|
||||
#[dbus_interface(property)]
|
||||
fn awake_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
@@ -454,6 +441,7 @@ impl CtrlAnimeZbus {
|
||||
true
|
||||
}
|
||||
|
||||
/// Get the status of if factory system-status animations are enabled
|
||||
#[dbus_interface(property)]
|
||||
fn boot_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
@@ -462,6 +450,7 @@ impl CtrlAnimeZbus {
|
||||
true
|
||||
}
|
||||
|
||||
/// Notify listeners of the status of AniMe LED power and factory system-status animations
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_power_states(&self, data: &AnimePowerStates) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ use logind_zbus::{
|
||||
};
|
||||
use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
||||
use std::{io::Write, ops::Add, path::Path, time::Instant};
|
||||
use std::{iter::FromIterator, thread::JoinHandle};
|
||||
use std::{process::Command, thread::sleep, time::Duration};
|
||||
use std::{str::FromStr, sync::mpsc};
|
||||
use std::{sync::Arc, sync::Mutex};
|
||||
use sysfs_class::RuntimePM;
|
||||
use sysfs_class::{PciDevice, SysClass};
|
||||
use system::{GraphicsDevice, PciBus};
|
||||
|
||||
@@ -66,24 +66,32 @@ impl CtrlGraphics {
|
||||
let mut nvidia = Vec::new();
|
||||
let mut other = Vec::new();
|
||||
for dev in devs.iter() {
|
||||
let c = dev.class()?;
|
||||
let c = dev.class().map_err(|err| {
|
||||
error!(
|
||||
"GFX: device error: {}, {}",
|
||||
dev.path().to_string_lossy(),
|
||||
err
|
||||
);
|
||||
err
|
||||
})?;
|
||||
if 0x03 == (c >> 16) & 0xFF {
|
||||
match dev.vendor()? {
|
||||
0x1002 => {
|
||||
info!("GFX: {}: AMD graphics", dev.id());
|
||||
amd.push(GraphicsDevice::new(dev.id().to_owned(), functions(&dev)));
|
||||
amd.push(GraphicsDevice::new(dev.id().to_owned(), functions(dev)));
|
||||
}
|
||||
0x10DE => {
|
||||
info!("GFX: {}: NVIDIA graphics", dev.id());
|
||||
nvidia.push(GraphicsDevice::new(dev.id().to_owned(), functions(&dev)));
|
||||
dev.set_runtime_pm(sysfs_class::RuntimePowerManagement::On)?;
|
||||
nvidia.push(GraphicsDevice::new(dev.id().to_owned(), functions(dev)));
|
||||
}
|
||||
0x8086 => {
|
||||
info!("GFX: {}: Intel graphics", dev.id());
|
||||
intel.push(GraphicsDevice::new(dev.id().to_owned(), functions(&dev)));
|
||||
intel.push(GraphicsDevice::new(dev.id().to_owned(), functions(dev)));
|
||||
}
|
||||
vendor => {
|
||||
info!("GFX: {}: Other({:X}) graphics", dev.id(), vendor);
|
||||
other.push(GraphicsDevice::new(dev.id().to_owned(), functions(&dev)));
|
||||
other.push(GraphicsDevice::new(dev.id().to_owned(), functions(dev)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +125,7 @@ impl CtrlGraphics {
|
||||
}
|
||||
|
||||
/// Associated method to get which vendor mode is set
|
||||
pub fn get_gfx_mode(&self) -> Result<GfxVendors, RogError> {
|
||||
pub(super) fn get_gfx_mode(&self) -> Result<GfxVendors, RogError> {
|
||||
if let Ok(config) = self.config.lock() {
|
||||
if let Some(mode) = config.gfx_tmp_mode {
|
||||
return Ok(mode);
|
||||
@@ -256,16 +264,17 @@ impl CtrlGraphics {
|
||||
let unbinds = devices.iter().map(|dev| dev.unbind());
|
||||
// Remove NVIDIA graphics devices and their functions
|
||||
let removes = devices.iter().map(|dev| dev.remove());
|
||||
Result::from_iter(unbinds.chain(removes))
|
||||
unbinds.chain(removes).collect::<Result<_, _>>()
|
||||
.map_err(|err| RogError::Command("device unbind error".into(), err))
|
||||
}
|
||||
|
||||
fn unbind_only(devices: &[GraphicsDevice]) -> Result<(), RogError> {
|
||||
let unbinds = devices.iter().map(|dev| dev.unbind());
|
||||
Result::from_iter(unbinds)
|
||||
unbinds.collect::<Result<_, _>>()
|
||||
.map_err(|err| RogError::Command("device unbind error".into(), err))
|
||||
}
|
||||
|
||||
/// Add or remove driver modules
|
||||
fn do_driver_action(driver: &str, action: &str) -> Result<(), GfxError> {
|
||||
let mut cmd = Command::new(action);
|
||||
cmd.arg(driver);
|
||||
@@ -350,14 +359,15 @@ impl CtrlGraphics {
|
||||
|
||||
let mut count = 0;
|
||||
|
||||
while count <= 5 {
|
||||
while count <= (4 * 3) {
|
||||
// 3 seconds max
|
||||
let output = cmd
|
||||
.output()
|
||||
.map_err(|err| RogError::Command(format!("{:?}", cmd), err))?;
|
||||
if output.stdout.starts_with(state.as_bytes()) {
|
||||
return Ok(());
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
std::thread::sleep(std::time::Duration::from_millis(250));
|
||||
count += 1;
|
||||
}
|
||||
Err(GfxError::DisplayManagerTimeout(state.into()).into())
|
||||
@@ -365,9 +375,10 @@ impl CtrlGraphics {
|
||||
|
||||
/// Determine if we need to logout/thread. Integrated<->Vfio mode does not
|
||||
/// require logout.
|
||||
fn logout_required(&self, vendor: GfxVendors) -> GfxRequiredUserAction {
|
||||
fn is_logout_required(&self, vendor: GfxVendors) -> GfxRequiredUserAction {
|
||||
if let Ok(config) = self.config.lock() {
|
||||
let current = config.gfx_mode;
|
||||
// Modes that can switch without logout
|
||||
if matches!(
|
||||
current,
|
||||
GfxVendors::Integrated | GfxVendors::Vfio | GfxVendors::Compute
|
||||
@@ -377,22 +388,28 @@ impl CtrlGraphics {
|
||||
) {
|
||||
return GfxRequiredUserAction::None;
|
||||
}
|
||||
// Modes that require a switch to integrated first
|
||||
if matches!(current, GfxVendors::Nvidia | GfxVendors::Hybrid)
|
||||
&& matches!(vendor, GfxVendors::Compute | GfxVendors::Vfio)
|
||||
{
|
||||
return GfxRequiredUserAction::Integrated;
|
||||
}
|
||||
}
|
||||
GfxRequiredUserAction::Logout
|
||||
}
|
||||
|
||||
/// Write the config changes and add/remove drivers and devices depending
|
||||
/// on selected mode:
|
||||
/// Do a full setup flow for the chosen mode:
|
||||
///
|
||||
/// Tasks:
|
||||
/// - rescan for devices
|
||||
/// - write xorg config
|
||||
/// - write modprobe config
|
||||
/// - rescan for devices
|
||||
/// + add drivers
|
||||
/// + or remove drivers and devices
|
||||
///
|
||||
/// The daemon needs direct access to this function when it detects that the
|
||||
pub fn do_vendor_tasks(
|
||||
/// bios has G-Sync switch is enabled
|
||||
pub fn do_mode_setup_tasks(
|
||||
vendor: GfxVendors,
|
||||
vfio_enable: bool,
|
||||
devices: &[GraphicsDevice],
|
||||
@@ -400,8 +417,30 @@ impl CtrlGraphics {
|
||||
) -> Result<(), RogError> {
|
||||
// Rescan before doing remove or add drivers
|
||||
bus.rescan()?;
|
||||
//
|
||||
Self::write_xorg_conf(vendor)?;
|
||||
// Make sure the power management is set to auto for nvidia devices
|
||||
let devs = PciDevice::all()?;
|
||||
for dev in devs.iter() {
|
||||
let c = dev.class().map_err(|err| {
|
||||
error!(
|
||||
"GFX: device error: {}, {}",
|
||||
dev.path().to_string_lossy(),
|
||||
err
|
||||
);
|
||||
err
|
||||
})?;
|
||||
if 0x03 == (c >> 16) & 0xFF && dev.vendor()? == 0x10DE {
|
||||
info!("GFX: {}: NVIDIA graphics, setting PM to auto", dev.id());
|
||||
dev.set_runtime_pm(sysfs_class::RuntimePowerManagement::On)?;
|
||||
}
|
||||
}
|
||||
// Only these modes should have xorg config
|
||||
if matches!(
|
||||
vendor,
|
||||
GfxVendors::Nvidia | GfxVendors::Hybrid | GfxVendors::Integrated
|
||||
) {
|
||||
Self::write_xorg_conf(vendor)?;
|
||||
}
|
||||
|
||||
// Write different modprobe to enable boot control to work
|
||||
Self::write_modprobe_conf(vendor, devices)?;
|
||||
|
||||
@@ -422,7 +461,7 @@ impl CtrlGraphics {
|
||||
for driver in NVIDIA_DRIVERS.iter() {
|
||||
Self::do_driver_action(driver, "rmmod")?;
|
||||
}
|
||||
Self::unbind_only(&devices)?;
|
||||
Self::unbind_only(devices)?;
|
||||
Self::do_driver_action("vfio-pci", "modprobe")?;
|
||||
} else {
|
||||
return Err(GfxError::VfioDisabled.into());
|
||||
@@ -438,7 +477,7 @@ impl CtrlGraphics {
|
||||
for driver in NVIDIA_DRIVERS.iter() {
|
||||
Self::do_driver_action(driver, "rmmod")?;
|
||||
}
|
||||
Self::unbind_remove_nvidia(&devices)?;
|
||||
Self::unbind_remove_nvidia(devices)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -467,7 +506,7 @@ impl CtrlGraphics {
|
||||
}
|
||||
|
||||
/// Spools until all user sessions are ended then switches to requested mode
|
||||
fn fire_starter(
|
||||
fn create_mode_change_thread(
|
||||
vendor: GfxVendors,
|
||||
devices: Vec<GraphicsDevice>,
|
||||
bus: PciBus,
|
||||
@@ -513,20 +552,31 @@ impl CtrlGraphics {
|
||||
Self::do_display_manager_action("stop")?;
|
||||
Self::wait_display_manager_state("inactive")?;
|
||||
|
||||
let vfio_enable = if let Ok(mut config) = config.try_lock() {
|
||||
let mut mode_to_save = vendor;
|
||||
// Need to change to integrated before we can change to vfio or compute
|
||||
if let Ok(mut config) = config.try_lock() {
|
||||
// Since we have a lock, reset tmp to none. This thread should only ever run
|
||||
// for Integrated, Hybrid, or Nvidia. Tmp is also only for informational
|
||||
config.gfx_tmp_mode = None;
|
||||
//
|
||||
config.gfx_vfio_enable
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let vfio_enable = config.gfx_vfio_enable;
|
||||
|
||||
// Failsafe. In the event this loop is run with a switch from nvidia in use
|
||||
// to vfio or compute do a forced switch to integrated instead to prevent issues
|
||||
if matches!(vendor, GfxVendors::Compute | GfxVendors::Vfio)
|
||||
&& matches!(config.gfx_mode, GfxVendors::Nvidia | GfxVendors::Hybrid)
|
||||
{
|
||||
Self::do_mode_setup_tasks(GfxVendors::Integrated, vfio_enable, &devices, &bus)?;
|
||||
Self::do_display_manager_action("restart")?;
|
||||
mode_to_save = GfxVendors::Integrated;
|
||||
} else {
|
||||
Self::do_mode_setup_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
Self::do_display_manager_action("restart")?;
|
||||
}
|
||||
}
|
||||
|
||||
Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
Self::do_display_manager_action("restart")?;
|
||||
// Save selected mode in case of reboot
|
||||
Self::save_gfx_mode(vendor, config);
|
||||
Self::save_gfx_mode(mode_to_save, config);
|
||||
info!("GFX thread: display-manager started");
|
||||
|
||||
let v: &str = vendor.into();
|
||||
@@ -535,7 +585,7 @@ impl CtrlGraphics {
|
||||
}
|
||||
|
||||
/// Before starting a new thread the old one *must* be cancelled
|
||||
fn cancel_thread(&self) {
|
||||
fn cancel_mode_change_thread(&self) {
|
||||
if let Ok(lock) = self.thread_kill.lock() {
|
||||
if let Some(tx) = lock.as_ref() {
|
||||
// Cancel the running thread
|
||||
@@ -550,7 +600,7 @@ impl CtrlGraphics {
|
||||
}
|
||||
|
||||
/// The thread is used only in cases where a logout is required
|
||||
fn setup_thread(&mut self, vendor: GfxVendors) {
|
||||
fn setup_mode_change_thread(&mut self, vendor: GfxVendors) {
|
||||
let config = self.config.clone();
|
||||
let devices = self.nvidia.clone();
|
||||
let bus = self.bus.clone();
|
||||
@@ -558,16 +608,16 @@ impl CtrlGraphics {
|
||||
if let Ok(mut lock) = self.thread_kill.lock() {
|
||||
*lock = Some(tx);
|
||||
}
|
||||
let killer = self.thread_kill.clone();
|
||||
let thread_kill = self.thread_kill.clone();
|
||||
|
||||
let _join: JoinHandle<()> = std::thread::spawn(move || {
|
||||
Self::fire_starter(vendor, devices, bus, rx, config)
|
||||
std::thread::spawn(move || {
|
||||
Self::create_mode_change_thread(vendor, devices, bus, rx, config)
|
||||
.map_err(|err| {
|
||||
error!("GFX: {}", err);
|
||||
})
|
||||
.ok();
|
||||
// clear the tx/rx when done
|
||||
if let Ok(mut lock) = killer.try_lock() {
|
||||
if let Ok(mut lock) = thread_kill.try_lock() {
|
||||
*lock = None;
|
||||
}
|
||||
});
|
||||
@@ -578,10 +628,7 @@ impl CtrlGraphics {
|
||||
/// to switch modes.
|
||||
///
|
||||
/// For manually calling (not on boot/startup) via dbus
|
||||
pub fn set_gfx_config(
|
||||
&mut self,
|
||||
vendor: GfxVendors,
|
||||
) -> Result<GfxRequiredUserAction, RogError> {
|
||||
pub fn set_gfx_mode(&mut self, vendor: GfxVendors) -> Result<GfxRequiredUserAction, RogError> {
|
||||
if let Ok(gsync) = CtrlRogBios::get_gfx_mode() {
|
||||
if gsync == 1 {
|
||||
return Err(GfxError::GsyncModeActive.into());
|
||||
@@ -599,27 +646,40 @@ impl CtrlGraphics {
|
||||
}
|
||||
|
||||
// Must always cancel any thread running
|
||||
self.cancel_thread();
|
||||
self.cancel_mode_change_thread();
|
||||
// determine which method we need here
|
||||
let action_required = self.logout_required(vendor);
|
||||
if matches!(action_required, GfxRequiredUserAction::Logout) {
|
||||
// Yeah need the thread to check if all users are logged out
|
||||
info!("GFX: mode change requires a logout to complete");
|
||||
self.setup_thread(vendor);
|
||||
} else {
|
||||
// Okay cool, we can switch on/off vfio
|
||||
info!("GFX: mode change does not require logout");
|
||||
let devices = self.nvidia.clone();
|
||||
let bus = self.bus.clone();
|
||||
Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
info!("GFX: Graphics mode changed to {}", <&str>::from(vendor));
|
||||
if matches!(vendor, GfxVendors::Vfio | GfxVendors::Compute) {
|
||||
let action_required = self.is_logout_required(vendor);
|
||||
|
||||
match action_required {
|
||||
GfxRequiredUserAction::Logout => {
|
||||
info!("GFX: mode change requires a logout to complete");
|
||||
self.setup_mode_change_thread(vendor);
|
||||
}
|
||||
GfxRequiredUserAction::Reboot => {
|
||||
info!("GFX: mode change requires reboot");
|
||||
let devices = self.nvidia.clone();
|
||||
let bus = self.bus.clone();
|
||||
Self::do_mode_setup_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
info!("GFX: Graphics mode changed to {}", <&str>::from(vendor));
|
||||
}
|
||||
GfxRequiredUserAction::Integrated => {
|
||||
info!("GFX: mode change requires user to be in Integrated mode first");
|
||||
}
|
||||
GfxRequiredUserAction::None => {
|
||||
info!("GFX: mode change does not require logout");
|
||||
let devices = self.nvidia.clone();
|
||||
let bus = self.bus.clone();
|
||||
Self::do_mode_setup_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
info!("GFX: Graphics mode changed to {}", <&str>::from(vendor));
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
config.gfx_tmp_mode = Some(vendor);
|
||||
};
|
||||
config.gfx_tmp_mode = None;
|
||||
if matches!(vendor, GfxVendors::Vfio | GfxVendors::Compute) {
|
||||
config.gfx_tmp_mode = Some(vendor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: undo if failed? Save last mode, catch errors...
|
||||
|
||||
Ok(action_required)
|
||||
}
|
||||
|
||||
@@ -635,7 +695,7 @@ impl CtrlGraphics {
|
||||
false
|
||||
};
|
||||
|
||||
Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
Self::do_mode_setup_tasks(vendor, vfio_enable, &devices, &bus)?;
|
||||
Self::toggle_fallback_service(vendor)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ impl GraphicsDevice {
|
||||
Ok(driver) => {
|
||||
info!("{}: Unbinding {}", driver.id(), func.id());
|
||||
unsafe {
|
||||
driver.unbind(&func).map_err(|err| {
|
||||
driver.unbind(func).map_err(|err| {
|
||||
error!("gfx unbind: {}", err);
|
||||
err
|
||||
})?;
|
||||
@@ -109,7 +109,7 @@ impl GraphicsDevice {
|
||||
Ok(driver) => {
|
||||
info!("{}: Binding {}", driver.id(), func.id());
|
||||
unsafe {
|
||||
driver.bind(&func).map_err(|err| {
|
||||
driver.bind(func).map_err(|err| {
|
||||
error!("gfx bind: {}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
@@ -25,7 +25,7 @@ impl CtrlGraphics {
|
||||
|
||||
fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result<GfxRequiredUserAction> {
|
||||
info!("GFX: Switching gfx mode to {}", <&str>::from(vendor));
|
||||
let msg = self.set_gfx_config(vendor).map_err(|err| {
|
||||
let msg = self.set_gfx_mode(vendor).map_err(|err| {
|
||||
error!("GFX: {}", err);
|
||||
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
||||
})?;
|
||||
|
||||
@@ -5,8 +5,10 @@ use crate::{
|
||||
config_aura::AuraConfig,
|
||||
error::RogError,
|
||||
laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES},
|
||||
CtrlTask,
|
||||
};
|
||||
use log::{info, warn};
|
||||
use logind_zbus::ManagerProxy;
|
||||
use rog_aura::{
|
||||
usb::{
|
||||
LED_APPLY, LED_AWAKE_OFF_SLEEP_OFF, LED_AWAKE_OFF_SLEEP_ON, LED_AWAKE_ON_SLEEP_OFF,
|
||||
@@ -15,11 +17,12 @@ use rog_aura::{
|
||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||
};
|
||||
use rog_types::supported::LedSupportedFunctions;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::{fs::OpenOptions, thread::spawn};
|
||||
use zbus::Connection;
|
||||
|
||||
use crate::GetSupported;
|
||||
|
||||
@@ -50,32 +53,80 @@ pub struct CtrlKbdLed {
|
||||
pub config: AuraConfig,
|
||||
}
|
||||
|
||||
pub struct CtrlKbdLedTask(pub Arc<Mutex<CtrlKbdLed>>);
|
||||
pub struct CtrlKbdLedTask<'a> {
|
||||
inner: Arc<Mutex<CtrlKbdLed>>,
|
||||
_c: Connection,
|
||||
manager: ManagerProxy<'a>,
|
||||
}
|
||||
|
||||
impl crate::CtrlTask for CtrlKbdLedTask {
|
||||
fn do_task(&self) -> Result<(), RogError> {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&lock.bright_node)
|
||||
.map_err(|err| match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
RogError::MissingLedBrightNode((&lock.bright_node).into(), err)
|
||||
}
|
||||
_ => RogError::Path((&lock.bright_node).into(), err),
|
||||
})?;
|
||||
let mut buf = [0u8; 1];
|
||||
file.read_exact(&mut buf)
|
||||
.map_err(|err| RogError::Read("buffer".into(), err))?;
|
||||
if let Some(num) = char::from(buf[0]).to_digit(10) {
|
||||
if lock.config.brightness != num.into() {
|
||||
lock.config.read();
|
||||
lock.config.brightness = num.into();
|
||||
lock.config.write();
|
||||
impl<'a> CtrlKbdLedTask<'a> {
|
||||
pub fn new(inner: Arc<Mutex<CtrlKbdLed>>) -> Self {
|
||||
let connection = Connection::new_system().unwrap();
|
||||
|
||||
let manager = ManagerProxy::new(&connection).unwrap();
|
||||
|
||||
let c1 = inner.clone();
|
||||
// Run this action when the system wakes up from sleep
|
||||
manager
|
||||
.connect_prepare_for_sleep(move |sleep| {
|
||||
if !sleep {
|
||||
let c1 = c1.clone();
|
||||
spawn(move || {
|
||||
// wait a fraction for things to wake up properly
|
||||
//std::thread::sleep(Duration::from_millis(100));
|
||||
loop {
|
||||
if let Ok(ref mut lock) = c1.try_lock() {
|
||||
lock.set_brightness(lock.config.brightness).ok();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return Ok(());
|
||||
Ok(())
|
||||
})
|
||||
.map_err(|err| {
|
||||
warn!("CtrlAnimeTask: new() {}", err);
|
||||
err
|
||||
})
|
||||
.ok();
|
||||
|
||||
Self {
|
||||
inner,
|
||||
_c: connection,
|
||||
manager,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&lock.bright_node)
|
||||
.map_err(|err| match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
RogError::MissingLedBrightNode((&lock.bright_node).into(), err)
|
||||
}
|
||||
_ => RogError::Path((&lock.bright_node).into(), err),
|
||||
})?;
|
||||
let mut buf = [0u8; 1];
|
||||
file.read_exact(&mut buf)
|
||||
.map_err(|err| RogError::Read("buffer".into(), err))?;
|
||||
if let Some(num) = char::from(buf[0]).to_digit(10) {
|
||||
if lock.config.brightness != num.into() {
|
||||
lock.config.read();
|
||||
lock.config.brightness = num.into();
|
||||
lock.config.write();
|
||||
}
|
||||
return Err(RogError::ParseLed);
|
||||
return Ok(());
|
||||
}
|
||||
Err(RogError::ParseLed)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CtrlTask for CtrlKbdLedTask<'a> {
|
||||
fn do_task(&self) -> Result<(), RogError> {
|
||||
self.manager.next_signal()?;
|
||||
if let Ok(ref mut lock) = self.inner.try_lock() {
|
||||
return Self::update_config(lock);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -319,7 +370,7 @@ impl CtrlKbdLed {
|
||||
|
||||
self.config.read();
|
||||
if let Some(data) = self.config.builtins.get(&next) {
|
||||
self.write_mode(&data)?;
|
||||
self.write_mode(data)?;
|
||||
self.config.current_mode = next;
|
||||
}
|
||||
self.config.write();
|
||||
@@ -330,7 +381,7 @@ impl CtrlKbdLed {
|
||||
|
||||
#[inline]
|
||||
fn write_mode(&self, mode: &AuraEffect) -> Result<(), RogError> {
|
||||
if !self.supported_modes.standard.contains(&mode.mode()) {
|
||||
if !self.supported_modes.standard.contains(mode.mode()) {
|
||||
return Err(RogError::NotSupported);
|
||||
}
|
||||
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::error::RogError;
|
||||
use crate::{config::Config, GetSupported};
|
||||
use log::info;
|
||||
use log::{info, warn};
|
||||
use rog_profiles::profiles::Profile;
|
||||
use rog_types::supported::FanCpuSupportedFunctions;
|
||||
use std::sync::Arc;
|
||||
@@ -23,12 +23,12 @@ impl GetSupported for CtrlFanAndCpu {
|
||||
}
|
||||
|
||||
impl crate::Reloadable for CtrlFanAndCpu {
|
||||
/// Fetcht he active profile and use that to set all related components up
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(mut cfg) = self.config.clone().try_lock() {
|
||||
let active = cfg.active_profile.clone();
|
||||
if let Some(existing) = cfg.power_profiles.get_mut(&active) {
|
||||
existing.set_system_all()?;
|
||||
cfg.write();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -38,31 +38,38 @@ impl crate::Reloadable for CtrlFanAndCpu {
|
||||
impl CtrlFanAndCpu {
|
||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||
Profile::get_fan_path()?;
|
||||
info!("Device has thermal throttle control");
|
||||
info!("Device has fan control available");
|
||||
Ok(CtrlFanAndCpu { config })
|
||||
}
|
||||
|
||||
/// Toggle to next profile in list
|
||||
pub(super) fn do_next_profile(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(mut config) = self.config.clone().try_lock() {
|
||||
// Read first just incase the user has modified the config before calling this
|
||||
config.read();
|
||||
|
||||
let mut i = config
|
||||
let mut toggle_index = config
|
||||
.toggle_profiles
|
||||
.binary_search(&config.active_profile)
|
||||
.unwrap_or(0)
|
||||
+ 1;
|
||||
if i >= config.toggle_profiles.len() {
|
||||
i = 0;
|
||||
if toggle_index >= config.toggle_profiles.len() {
|
||||
toggle_index = 0;
|
||||
}
|
||||
|
||||
let profile = config.toggle_profiles[i].clone();
|
||||
let profile = config.toggle_profiles[toggle_index].clone();
|
||||
|
||||
if let Some(existing) = config.power_profiles.get(&profile) {
|
||||
existing.set_system_all()?;
|
||||
config.active_profile = existing.name.clone();
|
||||
config.write();
|
||||
info!("Profile was changed to: {}", profile);
|
||||
info!("Profile was changed to: {}", &profile);
|
||||
} else {
|
||||
warn!(
|
||||
"toggle_profile {} does not exist in power_profiles",
|
||||
&profile
|
||||
);
|
||||
return Err(RogError::MissingProfile(profile.to_string()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -70,17 +77,25 @@ impl CtrlFanAndCpu {
|
||||
|
||||
pub(super) fn set_active(&mut self, profile: &str) -> Result<(), RogError> {
|
||||
if let Ok(mut config) = self.config.clone().try_lock() {
|
||||
// Read first just incase the user has modified the config before calling this
|
||||
config.read();
|
||||
if let Some(existing) = config.power_profiles.get(profile) {
|
||||
existing.set_system_all()?;
|
||||
config.active_profile = existing.name.clone();
|
||||
config.write();
|
||||
info!("Profile was changed to: {}", profile);
|
||||
} else {
|
||||
warn!(
|
||||
"toggle_profile {} does not exist in power_profiles",
|
||||
profile
|
||||
);
|
||||
return Err(RogError::MissingProfile(profile.to_string()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a new profile if the requested name doesn't exist, or modify existing
|
||||
pub(super) fn new_or_modify(&mut self, profile: &Profile) -> Result<(), RogError> {
|
||||
if let Ok(mut config) = self.config.clone().try_lock() {
|
||||
config.read();
|
||||
@@ -89,11 +104,12 @@ impl CtrlFanAndCpu {
|
||||
*existing = profile.clone();
|
||||
existing.set_system_all()?;
|
||||
} else {
|
||||
config.power_profiles
|
||||
config
|
||||
.power_profiles
|
||||
.insert(profile.name.clone(), profile.clone());
|
||||
profile.set_system_all()?;
|
||||
}
|
||||
|
||||
|
||||
config.active_profile = profile.name.clone();
|
||||
config.write();
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ impl FanAndCpuZbus {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
self.notify_profile(&profile)
|
||||
self.notify_profile(profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ impl GetSupported for CtrlRogBios {
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
RogBiosSupportedFunctions {
|
||||
post_sound_toggle: CtrlRogBios::check_path_exists(ASUS_POST_LOGO_SOUND).is_ok(),
|
||||
dedicated_gfx_toggle: CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE).is_ok(),
|
||||
post_sound_toggle: Path::new(ASUS_POST_LOGO_SOUND).exists(),
|
||||
dedicated_gfx_toggle: Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,8 +63,6 @@ impl CtrlRogBios {
|
||||
#[dbus_interface(signal)]
|
||||
pub fn notify_dedicated_graphic_mode(&self, dedicated: bool) -> zbus::Result<()> {}
|
||||
|
||||
// // // // // // // // // //
|
||||
|
||||
pub fn set_post_boot_sound(&mut self, on: bool) {
|
||||
Self::set_boot_sound(on)
|
||||
.map_err(|err| {
|
||||
@@ -116,22 +114,17 @@ impl crate::Reloadable for CtrlRogBios {
|
||||
|
||||
impl CtrlRogBios {
|
||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||
match CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE) {
|
||||
Ok(_) => {
|
||||
CtrlRogBios::set_path_mutable(ASUS_SWITCH_GRAPHIC_MODE)?;
|
||||
}
|
||||
Err(err) => {
|
||||
info!("ROG Switchable Graphics (bios) not detected: {}", err);
|
||||
}
|
||||
if Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists() {
|
||||
CtrlRogBios::set_path_mutable(ASUS_SWITCH_GRAPHIC_MODE)?;
|
||||
} else {
|
||||
info!("G-Sync Switchable Graphics not detected");
|
||||
info!("If your laptop is not a G-Sync enabled laptop then you can ignore this. Standard graphics switching will still work.");
|
||||
}
|
||||
|
||||
match CtrlRogBios::check_path_exists(ASUS_POST_LOGO_SOUND) {
|
||||
Ok(_) => {
|
||||
CtrlRogBios::set_path_mutable(ASUS_POST_LOGO_SOUND)?;
|
||||
}
|
||||
Err(err) => {
|
||||
info!("ROG boot sound toggle (bios) not detected: {}", err);
|
||||
}
|
||||
if Path::new(ASUS_POST_LOGO_SOUND).exists() {
|
||||
CtrlRogBios::set_path_mutable(ASUS_POST_LOGO_SOUND)?;
|
||||
} else {
|
||||
info!("Switch for POST boot sound not detected");
|
||||
}
|
||||
|
||||
Ok(CtrlRogBios { _config: config })
|
||||
@@ -147,19 +140,8 @@ impl CtrlRogBios {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_path_exists(path: &str) -> Result<(), RogError> {
|
||||
if Path::new(path).exists() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(RogError::MissingFunction(path.into()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_dedicated_gfx_toggle() -> bool {
|
||||
if CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE).is_ok() {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists()
|
||||
}
|
||||
|
||||
pub fn get_gfx_mode() -> Result<i8, RogError> {
|
||||
@@ -200,17 +182,6 @@ impl CtrlRogBios {
|
||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
||||
|
||||
self.update_initramfs(dedicated)?;
|
||||
|
||||
// if let Ok(ded) = CtrlRogBios::get_gfx_mode() {
|
||||
// if let Ok(vendor) = CtrlGraphics::get_vendor() {
|
||||
// if ded == 1 && vendor != "nvidia" {
|
||||
// warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode");
|
||||
// CtrlGraphics::set_gfx_config(&GfxVendors::Nvidia)
|
||||
// .unwrap_or_else(|err| warn!("Gfx controller: {}", err));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ use std::error::Error;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::env;
|
||||
|
||||
use daemon::ctrl_rog_bios::CtrlRogBios;
|
||||
use std::convert::Into;
|
||||
@@ -35,6 +36,18 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.filter(None, LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
let is_service = match env::var_os("IS_SERVICE") {
|
||||
Some(val) => val == "1",
|
||||
None => false,
|
||||
};
|
||||
|
||||
if !is_service {
|
||||
println!("asusd schould be only run from the right systemd service");
|
||||
println!("do not run in your terminal, if you need an logs please use journalctl -b -u asusd");
|
||||
println!("asusd will now exit");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
info!(" daemon v{}", daemon::VERSION);
|
||||
info!(" rog-anime v{}", rog_anime::VERSION);
|
||||
info!(" rog-aura v{}", rog_aura::VERSION);
|
||||
@@ -135,7 +148,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
.unwrap_or_else(|err| warn!("Keyboard LED control: {}", err));
|
||||
|
||||
CtrlKbdLedZbus::new(inner.clone()).add_to_server(&mut object_server);
|
||||
let task = CtrlKbdLedTask(inner);
|
||||
let task = CtrlKbdLedTask::new(inner);
|
||||
tasks.push(Box::new(task));
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -155,7 +168,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode");
|
||||
let devices = ctrl.devices();
|
||||
let bus = ctrl.bus();
|
||||
CtrlGraphics::do_vendor_tasks(
|
||||
CtrlGraphics::do_mode_setup_tasks(
|
||||
GfxVendors::Nvidia,
|
||||
false,
|
||||
&devices,
|
||||
@@ -165,7 +178,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
info!("Dedicated GFX toggle is off");
|
||||
let devices = ctrl.devices();
|
||||
let bus = ctrl.bus();
|
||||
CtrlGraphics::do_vendor_tasks(
|
||||
CtrlGraphics::do_mode_setup_tasks(
|
||||
config.gfx_mode,
|
||||
false,
|
||||
&devices,
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::ctrl_gfx::error::GfxError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RogError {
|
||||
ParseFanLevel,
|
||||
ParseVendor,
|
||||
ParseLed,
|
||||
MissingProfile(String),
|
||||
@@ -36,7 +35,6 @@ impl fmt::Display for RogError {
|
||||
// This trait requires `fmt` with this exact signature.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
RogError::ParseFanLevel => write!(f, "Parse profile error"),
|
||||
RogError::ParseVendor => write!(f, "Parse gfx vendor error"),
|
||||
RogError::ParseLed => write!(f, "Parse LED error"),
|
||||
RogError::MissingProfile(profile) => write!(f, "Profile does not exist {}", profile),
|
||||
|
||||
@@ -3,6 +3,7 @@ Description=ASUS Notebook Control
|
||||
After=basic.target syslog.target
|
||||
|
||||
[Service]
|
||||
Environment=IS_SERVICE=1
|
||||
ExecStart=/usr/bin/asusd
|
||||
Restart=on-failure
|
||||
Type=dbus
|
||||
|
||||
@@ -12,6 +12,13 @@ standard = ["Static", "Breathe", "Strobe", "Rainbow", "Star", "Rain", "Highlight
|
||||
multizone = false
|
||||
per_key = true
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "Zephyrus M"
|
||||
board_names = ["GM501GS"]
|
||||
standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"]
|
||||
multizone = true
|
||||
per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Zephyrus M15"
|
||||
board_names = ["GU502LW"]
|
||||
@@ -35,14 +42,14 @@ per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Strix"
|
||||
board_names = ["G531GW", "G733QS", "G733QR"]
|
||||
board_names = ["G531GW", "G533QR", "G733QS", "G733QR"]
|
||||
standard = ["Static", "Breathe", "Strobe", "Rainbow", "Star", "Rain", "Highlight", "Laser", "Ripple", "Pulse", "Comet", "Flash"]
|
||||
multizone = false
|
||||
per_key = true
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Strix"
|
||||
board_names = ["GX531", "G512LV", "G712LV", "G712LW"]
|
||||
board_names = ["GX531", "G512LV", "G712LV", "G712LW", "G513QY"]
|
||||
standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"]
|
||||
multizone = true
|
||||
per_key = false
|
||||
@@ -54,6 +61,13 @@ standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"]
|
||||
multizone = false
|
||||
per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Strix"
|
||||
board_names = ["G513IH"]
|
||||
standard = ["Static", "Breathe", "Strobe", "Rainbow", "Star", "Pulse"]
|
||||
multizone = true
|
||||
per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "Strix"
|
||||
board_names = ["G731GV", "G731GW", "G531GV"]
|
||||
@@ -89,6 +103,13 @@ standard = ["Static", "Breathe", "Pulse"]
|
||||
multizone = false
|
||||
per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Zephyrus G15"
|
||||
board_names = ["GA503Q"]
|
||||
standard = ["Static", "Breathe", "Pulse", "Rainbow", "Strobe"]
|
||||
multizone = false
|
||||
per_key = false
|
||||
|
||||
[[led_data]]
|
||||
prod_family = "ROG Zephyrus"
|
||||
board_names = ["GX550L"]
|
||||
|
||||
@@ -5,6 +5,8 @@ StartLimitBurst=2
|
||||
Before=display-manager.service
|
||||
|
||||
[Service]
|
||||
Environment=IS_SERVICE=1
|
||||
ExecStartPre=/bin/sleep 2
|
||||
ExecStart=/usr/bin/asusd
|
||||
Restart=on-failure
|
||||
Restart=always
|
||||
|
||||
86
data/icons/scalable/gpu-compute.svg
Normal file
86
data/icons/scalable/gpu-compute.svg
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Gravit.io -->
|
||||
|
||||
<svg
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 82.733002 82.733002"
|
||||
width="82.733002pt"
|
||||
height="82.733002pt"
|
||||
version="1.1"
|
||||
id="svg19"
|
||||
sodipodi:docname="gpu-compute.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview21"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.96875"
|
||||
inkscape:cx="15.597484"
|
||||
inkscape:cy="54.742138"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1083"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg19" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<clipPath
|
||||
id="_clipPath_ZEBBDq6ZtbLgkRXocTHUWTcRbcURZIva">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
id="rect2"
|
||||
x="0"
|
||||
y="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
clip-path="url(#_clipPath_ZEBBDq6ZtbLgkRXocTHUWTcRbcURZIva)"
|
||||
id="g17"
|
||||
transform="translate(-22.624,-23)">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
style="fill:#000000"
|
||||
fill-opacity="0"
|
||||
id="rect7"
|
||||
x="0"
|
||||
y="0" />
|
||||
<g
|
||||
id="g15">
|
||||
<path
|
||||
id="path9"
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#ed1c24;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 13.789062,13.789062 v 6.894532 H 0 v 6.894531 H 13.789062 V 41.367188 H 0 v 6.894531 H 13.789062 V 62.048828 H 0 v 6.894531 H 13.789062 V 82.732422 H 0 v 6.894531 h 13.789062 v 6.894531 h 6.894532 v 13.789066 h 6.894531 V 96.521484 h 13.789063 v 13.789066 h 6.894531 V 96.521484 h 13.789062 v 13.789066 h 6.892578 V 96.521484 h 13.789063 v 13.789066 h 6.896484 V 96.521484 h 6.894532 z"
|
||||
transform="matrix(0.75,0,0,0.75,22.624,23)" />
|
||||
<path
|
||||
id="path9-3"
|
||||
style="isolation:isolate;mix-blend-mode:normal;fill:#76b900;fill-opacity:1;stroke:#000000;stroke-width:0.375;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 95.016578,95.391113 -0.0051,-5.170896 10.341782,-0.01017 -0.005,-5.170896 -10.341789,0.01017 -0.01017,-10.341791 10.341799,-0.01018 -0.005,-5.170895 -10.341787,0.01018 -0.01017,-10.340328 10.341797,-0.01017 -0.005,-5.170896 -10.341794,0.01017 -0.01018,-10.341792 10.341784,-0.01017 -0.005,-5.170895 -10.341791,0.01017 -0.0051,-5.170897 -5.170898,0.0051 -0.01017,-10.341796 -5.170896,0.0051 0.01017,10.341797 -10.341792,0.01017 -0.01017,-10.341795 -5.170897,0.0051 0.01017,10.341796 -10.341791,0.01017 -0.01017,-10.341796 -5.169431,0.0051 0.01017,10.341795 -10.341792,0.01018 -0.01017,-10.341797 -5.172361,0.0051 0.01017,10.341795 -5.170894,0.0051 z" />
|
||||
<rect
|
||||
x="38.146"
|
||||
y="38.512001"
|
||||
width="51.708"
|
||||
height="51.708"
|
||||
fill="rgb(77,77,77)"
|
||||
id="rect11"
|
||||
style="fill:none" />
|
||||
<path
|
||||
d="m 67.238,81.543 c 3.416,0 7.169,-0.866 10.056,-2.262 l -1.395,-4.474 c -2.165,0.818 -4.86,1.299 -7.169,1.299 -7.313,0 -11.884,-4.811 -11.884,-12.317 0,-7.073 4.138,-11.114 11.162,-11.114 2.646,0 5.678,0.529 7.843,1.395 l 1.732,-4.811 c -2.839,-1.347 -6.111,-2.069 -9.43,-2.069 -10.537,0 -17.754,6.976 -17.754,17.465 0,10.104 6.832,16.888 16.839,16.888 z"
|
||||
fill="#dddddd"
|
||||
id="path13"
|
||||
style="stroke:#000000;stroke-opacity:1;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;fill:#ffffff" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
82
data/icons/scalable/gpu-hybrid.svg
Normal file
82
data/icons/scalable/gpu-hybrid.svg
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Gravit.io -->
|
||||
|
||||
<svg
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 82.733002 82.733002"
|
||||
width="82.733002pt"
|
||||
height="82.733002pt"
|
||||
version="1.1"
|
||||
id="svg19"
|
||||
sodipodi:docname="gpu-hybrid.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview21"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.96875"
|
||||
inkscape:cx="15.798742"
|
||||
inkscape:cy="54.742138"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1083"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg19" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<clipPath
|
||||
id="_clipPath_uVSrFPVusaaYDISWhfCjIlGBeb9FaZAr">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
id="rect2"
|
||||
x="0"
|
||||
y="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
clip-path="url(#_clipPath_uVSrFPVusaaYDISWhfCjIlGBeb9FaZAr)"
|
||||
id="g17"
|
||||
transform="translate(-22.624,-23)">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
style="fill:#000000"
|
||||
fill-opacity="0"
|
||||
id="rect7"
|
||||
x="0"
|
||||
y="0" />
|
||||
<g
|
||||
id="g15">
|
||||
<path
|
||||
d="m 38.137,23 v 10.342 h -5.171 v 5.17 H 22.624 v 5.171 H 32.966 V 54.025 H 22.624 v 5.171 H 32.966 V 69.537 H 22.624 v 5.171 H 32.966 V 85.05 H 22.624 v 5.17 h 10.342 v 5.171 h 5.171 v 10.342 h 5.171 V 95.391 h 10.341 v 10.342 H 58.82 V 95.391 h 10.342 v 10.342 h 5.17 V 95.391 h 10.342 v 10.342 h 5.171 V 95.391 h 5.171 V 90.22 h 10.341 V 85.05 H 95.016 V 74.708 h 10.341 V 69.537 H 95.016 V 59.196 h 10.341 V 54.025 H 95.016 V 43.683 h 10.341 V 38.512 H 95.016 v -5.17 H 89.845 V 23 H 84.674 V 33.342 H 74.332 V 23 h -5.17 V 33.342 H 58.82 V 23 H 53.649 V 33.342 H 43.308 V 23 Z"
|
||||
fill="rgb(77,77,77)"
|
||||
id="path9"
|
||||
style="fill:#ed1c24;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0.75;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<rect
|
||||
x="38.146"
|
||||
y="38.512001"
|
||||
width="51.708"
|
||||
height="51.708"
|
||||
fill="rgb(77,77,77)"
|
||||
id="rect11"
|
||||
style="fill:#76b900;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
|
||||
<path
|
||||
d="m 51.464,79 h 5.663 V 66.118 H 70.916 V 79 h 5.62 V 49 h -5.62 V 61.147 H 57.127 V 49 h -5.663 z"
|
||||
fill="rgb(221,221,221)"
|
||||
id="path13"
|
||||
style="fill:#ececec;stroke:#000000;stroke-opacity:1;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
52
data/icons/scalable/gpu-integrated.svg
Normal file
52
data/icons/scalable/gpu-integrated.svg
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Gravit.io -->
|
||||
|
||||
<svg
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 82.410369 82.410377"
|
||||
width="82.41037pt"
|
||||
height="82.410378pt"
|
||||
version="1.1"
|
||||
id="svg17"
|
||||
sodipodi:docname="gpu-integrated.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview19"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.96875"
|
||||
inkscape:cx="14.389937"
|
||||
inkscape:cy="54.742138"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1083"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg17" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<clipPath
|
||||
id="_clipPath_GAg6mcrkdqJgsmZOjvo6JT6R1d3r9FoI">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
id="rect2"
|
||||
x="0"
|
||||
y="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:#ed1c24;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 15.92217,76.9033 V 71.771223 H 13.28066 10.63915 V 69.129715 66.488208 H 5.507075 0.375 v -2.037735 -2.037735 h 5.132075 5.132075 v -5.73585 -5.73585 H 5.507075 0.375 V 48.903302 46.865566 H 5.507075 10.63915 V 41.205189 35.544811 H 5.507075 0.375 V 33.431604 31.318396 H 5.507075 10.63915 V 25.658019 19.997641 H 5.507075 0.375 V 17.959906 15.92217 h 5.132075 5.132075 v -2.641509 -2.64151 h 2.64151 2.64151 V 5.5070763 0.375 h 2.037736 2.037735 v 5.1320763 5.1320747 h 5.660378 5.660377 V 5.5070763 0.375 h 2.113207 2.113208 v 5.1320763 5.1320747 h 5.660377 5.660378 V 5.5070763 0.375 h 1.947066 1.947063 l 0.09711,1.8490563 c 0.07996,1.52246 0.251242,6.717377 0.253724,7.695141 0.0014,0.5274167 -0.04609,0.5197837 3.905982,0.6286047 1.618867,0.04457 3.945285,0.123799 5.16981,0.176053 l 2.226412,0.09501 V 5.5969303 0.375 h 2.037735 2.037743 v 5.1320763 5.1320747 h 2.641507 2.641508 v 2.64151 2.641509 h 5.132077 5.13207 v 2.037736 2.037735 h -5.13207 -5.132077 v 5.660378 5.660377 h 5.132077 5.13207 v 2.113208 2.113207 h -5.13207 -5.132077 v 5.660378 5.660377 h 5.132077 5.13207 v 2.037736 2.037736 h -5.13207 -5.132077 v 5.73585 5.73585 h 5.132077 5.13207 v 2.037735 2.037735 h -5.13207 -5.132077 v 2.641507 2.641508 H 69.129718 66.488211 V 76.9033 82.035378 H 64.450468 62.412733 V 76.9033 71.771223 h -5.73585 -5.735846 V 76.9033 82.035378 H 48.903301 46.865566 V 76.9033 71.771223 H 41.205188 35.544811 V 76.9033 82.035378 H 33.431603 31.318396 V 76.9033 71.771223 H 25.658019 19.997641 V 76.9033 82.035378 H 17.959906 15.92217 Z"
|
||||
id="path1355" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
52
data/icons/scalable/gpu-nvidia.svg
Normal file
52
data/icons/scalable/gpu-nvidia.svg
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Gravit.io -->
|
||||
|
||||
<svg
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 82.410369 82.410377"
|
||||
width="82.41037pt"
|
||||
height="82.410378pt"
|
||||
version="1.1"
|
||||
id="svg17"
|
||||
sodipodi:docname="gpu-nvidia.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview19"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.96875"
|
||||
inkscape:cx="14.389937"
|
||||
inkscape:cy="54.742138"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1083"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg17" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<clipPath
|
||||
id="_clipPath_GAg6mcrkdqJgsmZOjvo6JT6R1d3r9FoI">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
id="rect2"
|
||||
x="0"
|
||||
y="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:#76b900;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 15.92217,76.9033 V 71.771223 H 13.28066 10.63915 V 69.129715 66.488208 H 5.507075 0.375 v -2.037735 -2.037735 h 5.132075 5.132075 v -5.73585 -5.73585 H 5.507075 0.375 V 48.903302 46.865566 H 5.507075 10.63915 V 41.205189 35.544811 H 5.507075 0.375 V 33.431604 31.318396 H 5.507075 10.63915 V 25.658019 19.997641 H 5.507075 0.375 V 17.959906 15.92217 h 5.132075 5.132075 v -2.641509 -2.64151 h 2.64151 2.64151 V 5.5070763 0.375 h 2.037736 2.037735 v 5.1320763 5.1320747 h 5.660378 5.660377 V 5.5070763 0.375 h 2.113207 2.113208 v 5.1320763 5.1320747 h 5.660377 5.660378 V 5.5070763 0.375 h 1.947066 1.947063 l 0.09711,1.8490563 c 0.07996,1.52246 0.251242,6.717377 0.253724,7.695141 0.0014,0.5274167 -0.04609,0.5197837 3.905982,0.6286047 1.618867,0.04457 3.945285,0.123799 5.16981,0.176053 l 2.226412,0.09501 V 5.5969303 0.375 h 2.037735 2.037743 v 5.1320763 5.1320747 h 2.641507 2.641508 v 2.64151 2.641509 h 5.132077 5.13207 v 2.037736 2.037735 h -5.13207 -5.132077 v 5.660378 5.660377 h 5.132077 5.13207 v 2.113208 2.113207 h -5.13207 -5.132077 v 5.660378 5.660377 h 5.132077 5.13207 v 2.037736 2.037736 h -5.13207 -5.132077 v 5.73585 5.73585 h 5.132077 5.13207 v 2.037735 2.037735 h -5.13207 -5.132077 v 2.641507 2.641508 H 69.129718 66.488211 V 76.9033 82.035378 H 64.450468 62.412733 V 76.9033 71.771223 h -5.73585 -5.735846 V 76.9033 82.035378 H 48.903301 46.865566 V 76.9033 71.771223 H 41.205188 35.544811 V 76.9033 82.035378 H 33.431603 31.318396 V 76.9033 71.771223 H 25.658019 19.997641 V 76.9033 82.035378 H 17.959906 15.92217 Z"
|
||||
id="path1355" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
86
data/icons/scalable/gpu-vfio.svg
Normal file
86
data/icons/scalable/gpu-vfio.svg
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Gravit.io -->
|
||||
|
||||
<svg
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 82.733002 82.733002"
|
||||
width="82.733002pt"
|
||||
height="82.733002pt"
|
||||
version="1.1"
|
||||
id="svg19"
|
||||
sodipodi:docname="gpu-vfio.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview21"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="7.8686859"
|
||||
inkscape:cx="55.091791"
|
||||
inkscape:cy="55.155334"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1083"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg19" />
|
||||
<defs
|
||||
id="defs5">
|
||||
<clipPath
|
||||
id="_clipPath_ZEBBDq6ZtbLgkRXocTHUWTcRbcURZIva">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
id="rect2"
|
||||
x="0"
|
||||
y="0" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g
|
||||
clip-path="url(#_clipPath_ZEBBDq6ZtbLgkRXocTHUWTcRbcURZIva)"
|
||||
id="g17"
|
||||
transform="translate(-22.624,-23)">
|
||||
<rect
|
||||
width="128"
|
||||
height="128"
|
||||
style="fill:#000000"
|
||||
fill-opacity="0"
|
||||
id="rect7"
|
||||
x="0"
|
||||
y="0" />
|
||||
<g
|
||||
id="g15">
|
||||
<path
|
||||
id="path9"
|
||||
style="opacity:1;mix-blend-mode:normal;fill:#ed1c24;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 13.789062,13.789062 v 6.894532 H 0 v 6.894531 H 13.789062 V 41.367188 H 0 v 6.894531 H 13.789062 V 62.048828 H 0 v 6.894531 H 13.789062 V 82.732422 H 0 v 6.894531 h 13.789062 v 6.894531 h 6.894532 v 13.789066 h 6.894531 V 96.521484 h 13.789063 v 13.789066 h 6.894531 V 96.521484 h 13.789062 v 13.789066 h 6.892578 V 96.521484 h 13.789063 v 13.789066 h 6.896484 V 96.521484 h 6.894532 z"
|
||||
transform="matrix(0.75,0,0,0.75,22.624,23)" />
|
||||
<path
|
||||
id="path9-3"
|
||||
style="isolation:isolate;mix-blend-mode:normal;fill:#76b900;fill-opacity:1;stroke:#000000;stroke-width:0.375;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 95.016578,95.391113 -0.0051,-5.170896 10.341782,-0.01017 -0.005,-5.170896 -10.341789,0.01017 -0.01017,-10.341791 10.341799,-0.01018 -0.005,-5.170895 -10.341787,0.01018 -0.01017,-10.340328 10.341797,-0.01017 -0.005,-5.170896 -10.341794,0.01017 -0.01018,-10.341792 10.341784,-0.01017 -0.005,-5.170895 -10.341791,0.01017 -0.0051,-5.170897 -5.170898,0.0051 -0.01017,-10.341796 -5.170896,0.0051 0.01017,10.341797 -10.341792,0.01017 -0.01017,-10.341795 -5.170897,0.0051 0.01017,10.341796 -10.341791,0.01017 -0.01017,-10.341796 -5.169431,0.0051 0.01017,10.341795 -10.341792,0.01018 -0.01017,-10.341797 -5.172361,0.0051 0.01017,10.341795 -5.170894,0.0051 z" />
|
||||
<rect
|
||||
x="38.146"
|
||||
y="38.512001"
|
||||
width="51.708"
|
||||
height="51.708"
|
||||
fill="rgb(77,77,77)"
|
||||
id="rect11"
|
||||
style="fill:none" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
d="m 38.016104,57.595764 h 6.037 l 11.263,-31.267 h -5.947 l -8.064,24.374 -7.75,-24.374 h -6.758 z"
|
||||
fill="#dddddd"
|
||||
id="path849"
|
||||
style="isolation:isolate;stroke:#000000;stroke-opacity:1;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;fill:#ffffff" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
1
data/icons/scalable/notification-reboot.svg
Normal file
1
data/icons/scalable/notification-reboot.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="141 297.96 507.339 471.04" width="507.339pt" height="471.04pt"><g><g><g><g><path d=" M 537.075 443.463 L 537.075 443.463 L 564.723 427.335 C 504.903 324.571 375.966 285.313 269.027 337.304 L 269.027 297.96 L 237.027 297.96 L 237.027 393.96 L 333.027 393.96 L 333.027 361.96 L 292.147 361.96 C 382.665 323.563 487.612 358.486 537.075 443.463 Z " fill="rgb(204,64,64)"/><path d=" M 245.027 692.775 C 170.84 632.524 151.314 527.353 198.931 444.488 L 171.187 428.488 C 116.876 523.063 137.426 642.887 220.147 713.96 L 181.027 713.96 L 181.027 745.96 L 277.027 745.96 L 277.027 649.96 L 245.027 649.96 L 245.027 692.775 L 245.027 692.775 Z " fill="rgb(204,64,64)"/><path d=" M 580.451 499.048 L 512.579 566.936 L 535.203 589.56 L 562.403 562.36 C 551.734 661.49 468.201 736.724 368.499 737 L 368.499 769 C 487.289 768.688 585.833 677.011 594.707 558.552 L 625.715 589.56 L 648.339 566.936 L 580.451 499.048 Z " fill="rgb(204,64,64)"/></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rog_anime"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
#[cfg(feature = "dbus")]
|
||||
use zvariant_derive::Type;
|
||||
|
||||
use crate::{error::AnimeError, AnimTime, AnimeGif};
|
||||
|
||||
/// The first 7 bytes of a USB packet are accounted for by `USB_PREFIX1` and `USB_PREFIX2`
|
||||
const BLOCK_START: usize = 7;
|
||||
/// *Not* inclusive, the byte before this is the final for each "pane"
|
||||
@@ -79,3 +90,93 @@ impl From<AnimeDataBuffer> for AnimePacketType {
|
||||
buffers
|
||||
}
|
||||
}
|
||||
|
||||
/// This runs the animations as a blocking loop by using the `callback` to write data
|
||||
pub fn run_animation(
|
||||
frames: &AnimeGif,
|
||||
do_early_return: Arc<AtomicBool>,
|
||||
callback: &dyn Fn(AnimeDataBuffer),
|
||||
) -> Result<(), AnimeError> {
|
||||
let mut count = 0;
|
||||
let start = Instant::now();
|
||||
|
||||
let mut timed = false;
|
||||
let mut run_time = frames.total_frame_time();
|
||||
println!("Real gif run length = {:?}", run_time);
|
||||
if let AnimTime::Fade(time) = frames.duration() {
|
||||
if let Some(middle) = time.show_for() {
|
||||
run_time = middle + time.total_fade_time();
|
||||
}
|
||||
timed = true;
|
||||
} else if let AnimTime::Time(time) = frames.duration() {
|
||||
run_time = time;
|
||||
timed = true;
|
||||
}
|
||||
|
||||
// After setting up all the data
|
||||
let mut fade_in = Duration::from_millis(0);
|
||||
let mut fade_out = Duration::from_millis(0);
|
||||
let mut fade_in_step = 0.0;
|
||||
let mut fade_in_accum = 0.0;
|
||||
let mut fade_out_step = 0.0;
|
||||
let mut fade_out_accum;
|
||||
if let AnimTime::Fade(time) = frames.duration() {
|
||||
fade_in = time.fade_in();
|
||||
fade_out = time.fade_out();
|
||||
fade_in_step = 1.0 / fade_in.as_secs_f32();
|
||||
fade_out_step = 1.0 / fade_out.as_secs_f32();
|
||||
|
||||
if time.total_fade_time() > run_time {
|
||||
println!("Total fade in/out time larger than gif run time. Setting fades to half");
|
||||
fade_in = run_time / 2;
|
||||
fade_in_step = 1.0 / (run_time / 2).as_secs_f32();
|
||||
|
||||
fade_out = run_time / 2;
|
||||
fade_out_step = 1.0 / (run_time / 2).as_secs_f32();
|
||||
}
|
||||
}
|
||||
|
||||
'animation: loop {
|
||||
for frame in frames.frames() {
|
||||
let frame_start = Instant::now();
|
||||
if do_early_return.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
let mut output = frame.frame().clone();
|
||||
|
||||
if let AnimTime::Fade(_) = frames.duration() {
|
||||
if frame_start <= start + fade_in {
|
||||
for pixel in output.get_mut() {
|
||||
*pixel = (*pixel as f32 * fade_in_accum) as u8;
|
||||
}
|
||||
fade_in_accum = fade_in_step * (frame_start - start).as_secs_f32();
|
||||
} else if frame_start > (start + run_time) - fade_out {
|
||||
if run_time > (frame_start - start) {
|
||||
fade_out_accum =
|
||||
fade_out_step * (run_time - (frame_start - start)).as_secs_f32();
|
||||
} else {
|
||||
fade_out_accum = 0.0;
|
||||
}
|
||||
for pixel in output.get_mut() {
|
||||
*pixel = (*pixel as f32 * fade_out_accum) as u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(output);
|
||||
|
||||
if timed && Instant::now().duration_since(start) > run_time {
|
||||
break 'animation;
|
||||
}
|
||||
|
||||
sleep(frame.delay());
|
||||
}
|
||||
if let AnimTime::Count(times) = frames.duration() {
|
||||
count += 1;
|
||||
if count >= times {
|
||||
break 'animation;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -31,10 +31,12 @@ impl AnimeFrame {
|
||||
pub enum AnimTime {
|
||||
/// Time in milliseconds for animation to run
|
||||
Time(Duration),
|
||||
/// How many full animation loops to run
|
||||
Cycles(u32),
|
||||
/// How many full animation loops to run or how many seconds if image is static
|
||||
Count(u32),
|
||||
/// Run for infinite time
|
||||
Infinite,
|
||||
/// Fade in, play for, fade out
|
||||
Fade(Fade),
|
||||
}
|
||||
|
||||
impl Default for AnimTime {
|
||||
@@ -44,6 +46,40 @@ impl Default for AnimTime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fancy brightness control: fade in/out, show at brightness for n time
|
||||
#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
|
||||
pub struct Fade {
|
||||
fade_in: Duration,
|
||||
show_for: Option<Duration>,
|
||||
fade_out: Duration,
|
||||
}
|
||||
|
||||
impl Fade {
|
||||
pub fn new(fade_in: Duration, show_for: Option<Duration>, fade_out: Duration) -> Self {
|
||||
Self {
|
||||
fade_in,
|
||||
show_for,
|
||||
fade_out,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fade_in(&self) -> Duration {
|
||||
self.fade_in
|
||||
}
|
||||
|
||||
pub fn show_for(&self) -> Option<Duration> {
|
||||
self.show_for
|
||||
}
|
||||
|
||||
pub fn fade_out(&self) -> Duration {
|
||||
self.fade_out
|
||||
}
|
||||
|
||||
pub fn total_fade_time(&self) -> Duration {
|
||||
self.fade_in + self.fade_out
|
||||
}
|
||||
}
|
||||
|
||||
/// A gif animation. This is a collection of frames from the gif, and a duration
|
||||
/// that the animation should be shown for.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -67,6 +103,7 @@ impl AnimeGif {
|
||||
let mut decoder = decoder.read_info(file)?;
|
||||
|
||||
let mut frames = Vec::with_capacity(decoder.buffer_size());
|
||||
|
||||
while let Some(frame) = decoder.read_next_frame()? {
|
||||
let wait = frame.delay * 10;
|
||||
if matches!(frame.dispose, gif::DisposalMethod::Background) {
|
||||
@@ -162,6 +199,39 @@ impl AnimeGif {
|
||||
Ok(Self(frames, duration))
|
||||
}
|
||||
|
||||
/// Make a static gif out of a greyscale png. If no duration is specified then the default
|
||||
/// will be 1 second long. If `AnimTime::Cycles` is specified for `duration` then this can
|
||||
/// be considered how many seconds the image will show for.
|
||||
#[inline]
|
||||
pub fn create_png_static(
|
||||
file_name: &Path,
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
) -> Result<Self, AnimeError> {
|
||||
let image = AnimeImage::from_png(file_name, scale, angle, translation, brightness)?;
|
||||
|
||||
let mut total = Duration::from_millis(1000);
|
||||
if let AnimTime::Fade(fade) = duration {
|
||||
total = fade.total_fade_time();
|
||||
if let Some(middle) = fade.show_for {
|
||||
total += middle;
|
||||
}
|
||||
}
|
||||
// Make frame delay 30ms, and find frame count
|
||||
let frame_count = total.as_millis() / 30;
|
||||
|
||||
let single = AnimeFrame {
|
||||
data: <AnimeDataBuffer>::from(&image),
|
||||
delay: Duration::from_millis(30),
|
||||
};
|
||||
let frames = vec![single; frame_count as usize];
|
||||
|
||||
Ok(Self(frames, duration))
|
||||
}
|
||||
|
||||
/// Get a slice of the frames this gif has
|
||||
#[inline]
|
||||
pub fn frames(&self) -> &[AnimeFrame] {
|
||||
@@ -173,4 +243,16 @@ impl AnimeGif {
|
||||
pub fn duration(&self) -> AnimTime {
|
||||
self.1
|
||||
}
|
||||
|
||||
/// Get the frame count
|
||||
pub fn frame_count(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
/// Get total gif time for one run
|
||||
pub fn total_frame_time(&self) -> Duration {
|
||||
let mut time = 0;
|
||||
self.0.iter().for_each(|f| time += f.delay.as_millis());
|
||||
Duration::from_millis(time as u64)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
|
||||
use glam::Vec2;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@@ -11,14 +8,14 @@ use crate::{error::AnimeError, AnimTime, AnimeDataBuffer, AnimeGif, AnimeImage};
|
||||
/// All the possible AniMe actions that can be used. This enum is intended to be
|
||||
/// a helper for loading up `ActionData`.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub enum AnimeAction {
|
||||
pub enum ActionLoader {
|
||||
/// Full gif sequence. Immutable.
|
||||
AsusAnimation {
|
||||
file: PathBuf,
|
||||
time: AnimTime,
|
||||
brightness: f32,
|
||||
},
|
||||
/// Basic image, can have properties changed
|
||||
/// Animated gif. If the file is a png a static gif is created using the `time` properties
|
||||
ImageAnimation {
|
||||
file: PathBuf,
|
||||
scale: f32,
|
||||
@@ -32,6 +29,7 @@ pub enum AnimeAction {
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
time: Option<AnimTime>,
|
||||
brightness: f32,
|
||||
},
|
||||
/// A pause to be used between sequences
|
||||
@@ -59,44 +57,70 @@ pub enum ActionData {
|
||||
}
|
||||
|
||||
impl ActionData {
|
||||
pub fn from_anime_action(action: &AnimeAction) -> Result<ActionData, AnimeError> {
|
||||
pub fn from_anime_action(action: &ActionLoader) -> Result<ActionData, AnimeError> {
|
||||
let a = match action {
|
||||
AnimeAction::AsusAnimation {
|
||||
ActionLoader::AsusAnimation {
|
||||
file,
|
||||
time: duration,
|
||||
brightness,
|
||||
} => ActionData::Animation(AnimeGif::create_diagonal_gif(
|
||||
&file,
|
||||
file,
|
||||
*duration,
|
||||
*brightness,
|
||||
)?),
|
||||
AnimeAction::ImageAnimation {
|
||||
ActionLoader::ImageAnimation {
|
||||
file,
|
||||
scale,
|
||||
angle,
|
||||
translation,
|
||||
time: duration,
|
||||
brightness,
|
||||
} => ActionData::Animation(AnimeGif::create_png_gif(
|
||||
&file,
|
||||
*scale,
|
||||
*angle,
|
||||
*translation,
|
||||
*duration,
|
||||
*brightness,
|
||||
)?),
|
||||
AnimeAction::Image {
|
||||
} => {
|
||||
if let Some(ext) = file.extension() {
|
||||
if ext.to_string_lossy().to_lowercase() == "png" {
|
||||
return Ok(ActionData::Animation(AnimeGif::create_png_static(
|
||||
file,
|
||||
*scale,
|
||||
*angle,
|
||||
*translation,
|
||||
*duration,
|
||||
*brightness,
|
||||
)?));
|
||||
}
|
||||
}
|
||||
ActionData::Animation(AnimeGif::create_png_gif(
|
||||
file,
|
||||
*scale,
|
||||
*angle,
|
||||
*translation,
|
||||
*duration,
|
||||
*brightness,
|
||||
)?)
|
||||
}
|
||||
ActionLoader::Image {
|
||||
file,
|
||||
scale,
|
||||
angle,
|
||||
translation,
|
||||
brightness,
|
||||
time,
|
||||
} => {
|
||||
let image = AnimeImage::from_png(&file, *scale, *angle, *translation, *brightness)?;
|
||||
if let Some(time) = time {
|
||||
return Ok(ActionData::Animation(AnimeGif::create_png_static(
|
||||
file,
|
||||
*scale,
|
||||
*angle,
|
||||
*translation,
|
||||
*time,
|
||||
*brightness,
|
||||
)?));
|
||||
}
|
||||
// If no time then create a plain static image
|
||||
let image = AnimeImage::from_png(file, *scale, *angle, *translation, *brightness)?;
|
||||
let data = <AnimeDataBuffer>::from(&image);
|
||||
ActionData::Image(Box::new(data))
|
||||
}
|
||||
AnimeAction::Pause(duration) => ActionData::Pause(*duration),
|
||||
ActionLoader::Pause(duration) => ActionData::Pause(*duration),
|
||||
};
|
||||
Ok(a)
|
||||
}
|
||||
@@ -115,38 +139,8 @@ impl Sequences {
|
||||
/// Use a base `AnimeAction` to generate the precomputed data and insert in to
|
||||
/// the run buffer
|
||||
#[inline]
|
||||
pub fn insert(&mut self, index: usize, action: &AnimeAction) -> Result<(), AnimeError> {
|
||||
match action {
|
||||
AnimeAction::AsusAnimation {
|
||||
file,
|
||||
time: duration,
|
||||
brightness,
|
||||
} => self.insert_asus_gif(index, &file, *duration, *brightness)?,
|
||||
AnimeAction::ImageAnimation {
|
||||
file,
|
||||
scale,
|
||||
angle,
|
||||
translation,
|
||||
time: duration,
|
||||
brightness,
|
||||
} => self.insert_image_gif(
|
||||
index,
|
||||
&file,
|
||||
*scale,
|
||||
*angle,
|
||||
*translation,
|
||||
*duration,
|
||||
*brightness,
|
||||
)?,
|
||||
AnimeAction::Image {
|
||||
file,
|
||||
scale,
|
||||
angle,
|
||||
translation,
|
||||
brightness,
|
||||
} => self.insert_png(index, &file, *scale, *angle, *translation, *brightness)?,
|
||||
AnimeAction::Pause(duration) => self.insert_pause(index, *duration),
|
||||
};
|
||||
pub fn insert(&mut self, index: usize, action: &ActionLoader) -> Result<(), AnimeError> {
|
||||
self.0.insert(index, ActionData::from_anime_action(action)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -161,69 +155,9 @@ impl Sequences {
|
||||
None
|
||||
}
|
||||
|
||||
fn insert_asus_gif(
|
||||
&mut self,
|
||||
mut index: usize,
|
||||
file: &Path,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
) -> Result<(), AnimeError> {
|
||||
if index > self.0.len() {
|
||||
index = self.0.len() - 1;
|
||||
}
|
||||
let frames = AnimeGif::create_diagonal_gif(file, duration, brightness)?;
|
||||
self.0.insert(index, ActionData::Animation(frames));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn insert_png(
|
||||
&mut self,
|
||||
mut index: usize,
|
||||
file: &Path,
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
brightness: f32,
|
||||
) -> Result<(), AnimeError> {
|
||||
if index > self.0.len() {
|
||||
index = self.0.len() - 1;
|
||||
}
|
||||
let image = AnimeImage::from_png(file, scale, angle, translation, brightness)?;
|
||||
let data = <AnimeDataBuffer>::from(&image);
|
||||
self.0.insert(index, ActionData::Image(Box::new(data)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn insert_image_gif(
|
||||
&mut self,
|
||||
mut index: usize,
|
||||
file: &Path,
|
||||
scale: f32,
|
||||
angle: f32,
|
||||
translation: Vec2,
|
||||
duration: AnimTime,
|
||||
brightness: f32,
|
||||
) -> Result<(), AnimeError> {
|
||||
if index > self.0.len() {
|
||||
index = self.0.len() - 1;
|
||||
}
|
||||
let frames =
|
||||
AnimeGif::create_png_gif(file, scale, angle, translation, duration, brightness)?;
|
||||
self.0.insert(index, ActionData::Animation(frames));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn insert_pause(&mut self, mut index: usize, duration: Duration) {
|
||||
if index > self.0.len() {
|
||||
index = self.0.len() - 1;
|
||||
}
|
||||
self.0.insert(index, ActionData::Pause(duration));
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> ActionIterator {
|
||||
ActionIterator {
|
||||
actions: &self,
|
||||
actions: self,
|
||||
next_idx: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ impl Sequences {
|
||||
|
||||
pub fn iter(&self) -> ActionIterator {
|
||||
ActionIterator {
|
||||
actions: &self,
|
||||
actions: self,
|
||||
next_idx: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rog_dbus"
|
||||
version = "3.4.0"
|
||||
version = "3.5.1"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -54,6 +54,8 @@ impl<'a> DbusProxies<'a> {
|
||||
recv.receive_for(self.charge.proxy());
|
||||
recv.receive_for(self.gfx.proxy());
|
||||
recv.receive_for(self.profile.proxy());
|
||||
recv.receive_for(self.rog_bios.proxy());
|
||||
recv.receive_for(self.supported.proxy());
|
||||
recv
|
||||
}
|
||||
|
||||
@@ -95,6 +97,8 @@ pub struct Signals {
|
||||
pub led_power_state: Receiver<LedPowerStates>,
|
||||
pub anime_power_state: Receiver<AnimePowerStates>,
|
||||
pub charge: Receiver<u8>,
|
||||
pub bios_gsync: Receiver<bool>,
|
||||
pub bios_sound: Receiver<bool>,
|
||||
}
|
||||
|
||||
impl Signals {
|
||||
@@ -136,6 +140,16 @@ impl Signals {
|
||||
proxies.anime.connect_notify_power_states(tx)?;
|
||||
rx
|
||||
},
|
||||
bios_gsync: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.rog_bios.connect_notify_dedicated_graphic_mode(tx)?;
|
||||
rx
|
||||
},
|
||||
bios_sound: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.rog_bios.connect_notify_post_boot_sound(tx)?;
|
||||
rx
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -170,6 +184,8 @@ impl<'a> RogDbusClient<'a> {
|
||||
recv.receive_for(self.proxies.charge.proxy());
|
||||
recv.receive_for(self.proxies.gfx.proxy());
|
||||
recv.receive_for(self.proxies.profile.proxy());
|
||||
recv.receive_for(self.proxies.rog_bios.proxy());
|
||||
recv.receive_for(self.proxies.supported.proxy());
|
||||
recv
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,5 @@
|
||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data.
|
||||
//! Source: `Interface '/org/asuslinux/Anime' from service 'org.asuslinux.Daemon' on system bus`.
|
||||
//!
|
||||
//! You may prefer to adapt it, instead of using it verbatim.
|
||||
//!
|
||||
//! More information can be found in the
|
||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||
//! section of the zbus documentation.
|
||||
//!
|
||||
//! This DBus object implements
|
||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||
//!
|
||||
//! * [`zbus::fdo::IntrospectableProxy`]
|
||||
//! * [`zbus::fdo::PeerProxy`]
|
||||
//! * [`zbus::fdo::PropertiesProxy`]
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
||||
use std::sync::mpsc::Sender;
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -29,21 +7,27 @@ use zbus::{dbus_proxy, Connection, Result};
|
||||
default_path = "/org/asuslinux/Anime"
|
||||
)]
|
||||
trait Daemon {
|
||||
/// SetBootOnOff method
|
||||
/// Set whether the AniMe will show boot, suspend, or off animations
|
||||
fn set_boot_on_off(&self, status: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetOnOff method
|
||||
/// Set the global AniMe brightness
|
||||
fn set_brightness(&self, bright: f32) -> zbus::Result<()>;
|
||||
|
||||
/// Set whether the AniMe is displaying images/data
|
||||
fn set_on_off(&self, status: bool) -> zbus::Result<()>;
|
||||
|
||||
/// WriteDirect method
|
||||
/// Writes a data stream of length. Will force system thread to exit until it is restarted
|
||||
fn write(&self, input: &[u8]) -> zbus::Result<()>;
|
||||
|
||||
/// Get status of if the AniMe LEDs are on
|
||||
#[dbus_proxy(property)]
|
||||
fn awake_enabled(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// Get the status of if factory system-status animations are enabled
|
||||
#[dbus_proxy(property)]
|
||||
fn boot_enabled(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// Notify listeners of the status of AniMe LED power and factory system-status animations
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_power_states(&self, data: AnimePowerStates) -> zbus::Result<()>;
|
||||
}
|
||||
@@ -53,33 +37,39 @@ pub struct AnimeProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> AnimeProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(AnimeProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(AnimeProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Set whether the AniMe will show boot, suspend, or off animations
|
||||
#[inline]
|
||||
pub fn toggle_boot_on(&self, on: bool) -> Result<()> {
|
||||
pub fn set_system_animations(&self, on: bool) -> Result<()> {
|
||||
self.0.set_boot_on_off(on)
|
||||
}
|
||||
|
||||
/// Set whether the AniMe is displaying images/data
|
||||
#[inline]
|
||||
pub fn toggle_on(&self, on: bool) -> Result<()> {
|
||||
pub fn set_led_power(&self, on: bool) -> Result<()> {
|
||||
self.0.set_on_off(on)
|
||||
}
|
||||
|
||||
/// Writes a data stream of length. Will force system thread to exit until it is restarted
|
||||
#[inline]
|
||||
pub fn write(&self, input: AnimeDataBuffer) -> Result<()> {
|
||||
self.0.write(input.get())
|
||||
}
|
||||
|
||||
/// Get status of if the AniMe LEDs are on
|
||||
#[inline]
|
||||
pub fn awake_enabled(&self) -> Result<bool> {
|
||||
self.0.awake_enabled()
|
||||
}
|
||||
|
||||
/// Get the status of if factory system-status animations are enabled
|
||||
#[inline]
|
||||
pub fn boot_enabled(&self) -> Result<bool> {
|
||||
self.0.boot_enabled()
|
||||
|
||||
@@ -44,9 +44,10 @@ pub struct ChargeProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> ChargeProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(ChargeProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(ChargeProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -52,9 +52,10 @@ pub struct GfxProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> GfxProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(GfxProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(GfxProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -81,9 +81,10 @@ pub struct LedProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> LedProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(LedProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(LedProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -60,9 +60,10 @@ pub struct ProfileProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> ProfileProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(ProfileProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(ProfileProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
@@ -54,9 +54,10 @@ pub struct RogBiosProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> RogBiosProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(RogBiosProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(RogBiosProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
@@ -84,25 +85,20 @@ impl<'a> RogBiosProxy<'a> {
|
||||
#[inline]
|
||||
pub fn connect_notify_dedicated_graphic_mode(
|
||||
&self,
|
||||
dedicated: Arc<Mutex<Option<bool>>>,
|
||||
send: Sender<bool>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_dedicated_graphic_mode(move |data| {
|
||||
if let Ok(mut lock) = dedicated.lock() {
|
||||
*lock = Some(data);
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_post_boot_sound(
|
||||
&self,
|
||||
sound: Arc<Mutex<Option<bool>>>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
pub fn connect_notify_post_boot_sound(&self, send: Sender<bool>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_post_boot_sound(move |data| {
|
||||
if let Ok(mut lock) = sound.lock() {
|
||||
*lock = Some(data);
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,9 +36,10 @@ pub struct SupportProxy<'a>(DaemonProxy<'a>);
|
||||
impl<'a> SupportProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
Ok(SupportProxy(DaemonProxy::new(&conn)?))
|
||||
Ok(SupportProxy(DaemonProxy::new(conn)?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rog_profiles"
|
||||
version = "0.1.0"
|
||||
version = "0.1.2"
|
||||
authors = ["Luke D. Jones <luke@ljones.dev>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ use rog_fan_curve::CurveError;
|
||||
#[derive(Debug)]
|
||||
pub enum ProfileError {
|
||||
ParseFanLevel,
|
||||
MissingProfile(String),
|
||||
Path(String, std::io::Error),
|
||||
Read(String, std::io::Error),
|
||||
Write(String, std::io::Error),
|
||||
@@ -23,9 +22,6 @@ impl fmt::Display for ProfileError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ProfileError::ParseFanLevel => write!(f, "Parse profile error"),
|
||||
ProfileError::MissingProfile(profile) => {
|
||||
write!(f, "Profile does not exist {}", profile)
|
||||
}
|
||||
ProfileError::Path(path, error) => write!(f, "Path {}: {}", path, error),
|
||||
ProfileError::Read(path, error) => write!(f, "Read {}: {}", path, error),
|
||||
ProfileError::Write(path, error) => write!(f, "Write {}: {}", path, error),
|
||||
|
||||
@@ -86,6 +86,7 @@ impl From<GfxVendors> for &str {
|
||||
pub enum GfxRequiredUserAction {
|
||||
Logout,
|
||||
Reboot,
|
||||
Integrated,
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -94,6 +95,7 @@ impl From<&GfxRequiredUserAction> for &str {
|
||||
match gfx {
|
||||
GfxRequiredUserAction::Logout => "logout",
|
||||
GfxRequiredUserAction::Reboot => "reboot",
|
||||
GfxRequiredUserAction::Integrated => "switch to integrated first",
|
||||
GfxRequiredUserAction::None => "no action",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use rog_aura::AuraModeNum;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use zvariant_derive::Type;
|
||||
|
||||
#[derive(Serialize, Deserialize, Type, Debug)]
|
||||
@@ -39,3 +40,54 @@ pub struct RogBiosSupportedFunctions {
|
||||
pub post_sound_toggle: bool,
|
||||
pub dedicated_gfx_toggle: bool,
|
||||
}
|
||||
|
||||
impl fmt::Display for SupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{}", self.anime_ctrl)?;
|
||||
writeln!(f, "{}", self.charge_ctrl)?;
|
||||
writeln!(f, "{}", self.fan_cpu_ctrl)?;
|
||||
writeln!(f, "{}", self.keyboard_led)?;
|
||||
writeln!(f, "{}", self.rog_bios_ctrl)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AnimeSupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "AniMe Matrix:")?;
|
||||
writeln!(f, "\tAnime Matrix control: {}", self.0)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for ChargeSupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Charge:")?;
|
||||
writeln!(
|
||||
f,
|
||||
"\tBattery charge limit control: {}",
|
||||
self.charge_level_set
|
||||
)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for FanCpuSupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Fan:")?;
|
||||
writeln!(f, "\tStock fan modes: {}", self.stock_fan_modes)?;
|
||||
writeln!(f, "\tMin/max frequency: {}", self.min_max_freq)?;
|
||||
writeln!(f, "\tFan curve control: {}", self.fan_curve_set)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for LedSupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "LED:")?;
|
||||
writeln!(f, "\tBrightness control: {}", self.brightness_set)?;
|
||||
writeln!(f, "\tStock LED modes: {:?}", self.stock_led_modes)?;
|
||||
writeln!(f, "\tMultizone LED mode: {}", self.multizone_led_mode)?;
|
||||
writeln!(f, "\tPer key LED mode: {}", self.per_key_led_mode)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for RogBiosSupportedFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "ROG BIOS:")?;
|
||||
writeln!(f, "\tPOST sound toggle: {}", self.post_sound_toggle)?;
|
||||
writeln!(f, "\tDedicated GFX toggle: {}", self.dedicated_gfx_toggle)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user