Compare commits

...

13 Commits
3.6.2 ... 3.7.0

Author SHA1 Message Date
Luke D. Jones
b7e45d7305 Bump versions for release 2021-06-06 21:02:07 +12:00
Luke D. Jones
d9077db234 Bugfix configs 2021-06-06 20:58:19 +12:00
Luke D. Jones
439b006342 Force change to integrated if in nvidia or hybrid mode
Force change to integrated if in nvidia or hybrid mode and user tries
to switch to vfio or compute
2021-06-06 13:44:34 +12:00
Luke D. Jones
ffa74d52e5 Fix LED brightness apply on resume 2021-06-06 12:12:17 +12:00
Luke Jones
6ccdd703e6 Merge branch 'fluke/anime-fade' into 'main'
Fluke/anime fade

See merge request asus-linux/asusctl!62
2021-05-31 01:07:17 +00:00
Luke D. Jones
bb910344b8 Basic fade in/out of gifs 2021-05-31 10:06:35 +12:00
Luke D. Jones
b9c4ff9ca7 Add GA503Q led modes 2021-05-30 10:20:17 +12:00
Luke D. Jones
62a18d4e57 Minor cleanup of bios controller 2021-05-29 15:33:47 +12:00
Luke D. Jones
f520e381a9 Attempt to provide more info to users gfx switching 2021-05-29 11:42:15 +12:00
Luke D. Jones
1dd543ddf3 Simplify the notifier 2021-05-27 13:22:08 +12:00
Luke Jones
a7ef63bd8a Merge branch 'formatted_supported_functions_message' into 'main'
Improving message formatting of supported functions

See merge request asus-linux/asusctl!61
2021-05-26 19:44:47 +00:00
KoStard
db43c0f2a4 Improving message formatting of supported functions
- Implementing fmt::Display for SupportedFunctions and sub-structs
2021-05-26 20:09:44 +04:00
Luke D. Jones
f0e5bb4ad1 dbus: send/recv notifications for bios options 2021-05-26 21:17:45 +12:00
37 changed files with 854 additions and 528 deletions

View File

@@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
# [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

238
Cargo.lock generated
View File

@@ -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",
@@ -60,20 +60,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 +144,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 +196,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.0"
dependencies = [
"env_logger",
"log",
@@ -232,9 +231,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 +253,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]
[[package]]
@@ -264,27 +263,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 +305,7 @@ checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]
[[package]]
@@ -324,18 +323,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 +347,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 +357,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 +374,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 +395,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 +450,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 +497,7 @@ checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]
[[package]]
@@ -536,9 +548,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 +620,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 +636,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 +669,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 +773,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 +817,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 +845,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 +888,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 +918,7 @@ dependencies = [
[[package]]
name = "rog_dbus"
version = "3.4.0"
version = "3.5.0"
dependencies = [
"rog_anime",
"rog_aura",
@@ -909,7 +940,7 @@ dependencies = [
[[package]]
name = "rog_profiles"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"intel-pstate",
"rog_fan_curve",
@@ -932,9 +963,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 +997,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 +1028,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 +1051,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
dependencies = [
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]
[[package]]
@@ -1062,13 +1093,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 +1146,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 +1196,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 +1232,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 +1354,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]
[[package]]
@@ -1354,5 +1378,5 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.69",
"syn 1.0.72",
]

View File

@@ -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>**

View File

@@ -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"

View File

@@ -1,22 +1,33 @@
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::GfxVendors;
use std::error::Error;
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);
}
};
}
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 +47,17 @@ 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();
}
let x = do_notif(&format!(
"Keyboard LED mode changed to {}",
ledmode.mode_name()
))?;
last_led_notif = Some(x);
if let Ok(data) = signals.gfx_vendor.try_recv() {
notify!(do_gfx_notif, last_notification, &data);
}
}
}
@@ -100,11 +86,30 @@ 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)
macro_rules! base_notification {
($body:expr) => {
Notification::new()
.summary(NOTIF_HEADER)
.body($body)
.timeout(2000)
.show()
};
}
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> {
base_notification!(&format!(
"Graphics mode changed to {}",
<&str>::from(vendor)
))
}

View File

@@ -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,

View File

@@ -158,10 +158,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 {
@@ -223,7 +225,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{}", dat);
}
if let Some(chg_limit) = parsed.chg_limit {

View File

@@ -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"

View File

@@ -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(())
}

View File

@@ -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()

View File

@@ -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),
},
],
}

View File

@@ -1,6 +1,6 @@
[package]
name = "daemon"
version = "3.6.2"
version = "3.7.0"
license = "MPL-2.0"
readme = "README.md"
authors = ["Luke <luke@ljones.dev>"]

View File

@@ -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");

View File

@@ -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));
}
}

View File

@@ -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,

View File

@@ -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<()>;
}

View File

@@ -13,6 +13,7 @@ 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,7 +67,14 @@ 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 => {
@@ -75,6 +83,7 @@ impl CtrlGraphics {
}
0x10DE => {
info!("GFX: {}: NVIDIA graphics", dev.id());
dev.set_runtime_pm(sysfs_class::RuntimePowerManagement::On)?;
nvidia.push(GraphicsDevice::new(dev.id().to_owned(), functions(&dev)));
}
0x8086 => {
@@ -400,6 +409,22 @@ impl CtrlGraphics {
) -> Result<(), RogError> {
// Rescan before doing remove or add drivers
bus.rescan()?;
// 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)?;
}
}
//
Self::write_xorg_conf(vendor)?;
// Write different modprobe to enable boot control to work
@@ -513,20 +538,32 @@ 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;
if matches!(vendor, GfxVendors::Compute | GfxVendors::Vfio)
&& matches!(config.gfx_mode, GfxVendors::Nvidia | GfxVendors::Hybrid)
{
Self::do_vendor_tasks(GfxVendors::Integrated, vfio_enable, &devices, &bus)?;
Self::do_display_manager_action("restart")?;
sleep(Duration::from_millis(1000)); // Allow some time for the desktop to start
Self::do_vendor_tasks(vendor, vfio_enable, &devices, &bus)?;
config.gfx_tmp_mode = Some(vendor);
mode_to_save = GfxVendors::Integrated;
} else {
Self::do_vendor_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();

View File

@@ -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::{fs::OpenOptions, thread::spawn};
use std::io::{Read, Write};
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::Connection;
use crate::GetSupported;
@@ -50,32 +53,79 @@ 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;
}}
});
}
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)
}
return Ok(());
_ => 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(())
}

View File

@@ -89,11 +89,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();
}

View File

@@ -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(())
}

View File

@@ -135,7 +135,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) => {

View File

@@ -89,6 +89,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"]

View File

@@ -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>"]

View File

@@ -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(())
}

View File

@@ -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)
}
}

View File

@@ -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,9 +57,9 @@ 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,
@@ -70,33 +68,59 @@ impl ActionData {
*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,
} => {
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,66 +155,6 @@ 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,

View File

@@ -1,6 +1,6 @@
[package]
name = "rog_dbus"
version = "3.4.0"
version = "3.5.0"
license = "MPL-2.0"
readme = "README.md"
authors = ["Luke <luke@ljones.dev>"]

View File

@@ -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
}

View File

@@ -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<()>;
}
@@ -56,30 +40,36 @@ impl<'a> AnimeProxy<'a> {
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()

View File

@@ -47,6 +47,7 @@ impl<'a> ChargeProxy<'a> {
Ok(ChargeProxy(DaemonProxy::new(&conn)?))
}
#[inline]
pub fn proxy(&self) -> &DaemonProxy<'a> {
&self.0
}

View File

@@ -55,6 +55,7 @@ impl<'a> GfxProxy<'a> {
Ok(GfxProxy(DaemonProxy::new(&conn)?))
}
#[inline]
pub fn proxy(&self) -> &DaemonProxy<'a> {
&self.0
}

View File

@@ -84,6 +84,7 @@ impl<'a> LedProxy<'a> {
Ok(LedProxy(DaemonProxy::new(&conn)?))
}
#[inline]
pub fn proxy(&self) -> &DaemonProxy<'a> {
&self.0
}

View File

@@ -63,6 +63,7 @@ impl<'a> ProfileProxy<'a> {
Ok(ProfileProxy(DaemonProxy::new(&conn)?))
}
#[inline]
pub fn proxy(&self) -> &DaemonProxy<'a> {
&self.0
}

View File

@@ -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};
@@ -57,6 +57,7 @@ impl<'a> RogBiosProxy<'a> {
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(())
})
}

View File

@@ -39,6 +39,7 @@ impl<'a> SupportProxy<'a> {
Ok(SupportProxy(DaemonProxy::new(&conn)?))
}
#[inline]
pub fn proxy(&self) -> &DaemonProxy<'a> {
&self.0
}

View File

@@ -1,6 +1,6 @@
[package]
name = "rog_profiles"
version = "0.1.0"
version = "0.1.1"
authors = ["Luke D. Jones <luke@ljones.dev>"]
edition = "2018"

View File

@@ -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)
}
}