Compare commits

...

41 Commits
3.6.2 ... 3.7.2

Author SHA1 Message Date
Luke Jones
49234af08b Merge branch 'fluke/profiles' into 'main'
Fluke/profiles

See merge request asus-linux/asusctl!71
2021-08-01 22:53:38 +00:00
Luke D. Jones
8f5717def8 Version bump, various fixes 2021-08-02 10:50:17 +12:00
Luke D. Jones
9e55c0b2ca Fix incorrect name match of Star keyboard effect 2021-08-02 10:28:50 +12:00
Luke Jones
dd6ee91364 Merge branch 'main' into 'main'
Enable multizone support on Strix 513IH

See merge request asus-linux/asusctl!69
2021-08-01 22:03:30 +00:00
Luke Jones
efbb838ca1 Merge branch 'G513QY-ledmodes' into 'main'
add G513QY ledmodes

See merge request asus-linux/asusctl!70
2021-08-01 21:27:59 +00:00
Sonny Piers
daf7d39d41 add G513QY ledmodes 2021-08-01 23:12:59 +02:00
pshem
28b1194924 Fix multizone support on Strix 513IH 2021-08-01 18:00:04 +01:00
Luke Jones
73d95ca187 Merge branch 'fluke/profiles' into 'main'
fix: Profile select by name is correctly choosing

Closes #96 and #100

See merge request asus-linux/asusctl!68
2021-07-31 12:19:28 +00:00
Luke D. Jones
00b7c6482f fix: remove the parsing for root supported functions 2021-08-01 00:15:38 +12:00
Luke D. Jones
29c26e8c89 fix: Profile select by name is correctly choosing
Closes #100 #96
2021-08-01 00:10:11 +12:00
Luke D. Jones
fb124dd228 Fix clippy warnings 2021-07-31 23:09:23 +12:00
Luke D. Jones
0599be02dc fix: remove dbg!() output 2021-07-31 23:03:17 +12:00
Luke Jones
81a88263a9 Merge branch 'fluke/cli-fixes' into 'main'
Fluke/cli fixes

See merge request asus-linux/asusctl!67
2021-07-31 11:00:43 +00:00
Luke D. Jones
cea1fd2540 Fix small issues with CLI 2021-07-31 22:57:17 +12:00
Luke Jones
f2ced3bc7c Merge branch 'main' into 'main'
Add Zephyrus M GM501GS

Closes #109

See merge request asus-linux/asusctl!66
2021-07-30 23:48:58 +00:00
pshem
dc2a05894b Add Zephyrus M GM501GS 2021-07-30 17:45:00 +01:00
Luke D. Jones
9ee962ad09 systemd: sleep 2 after unit init 2021-07-30 14:35:44 +12:00
Luke Jones
eb7ef0af4f Merge branch 'main' into 'main'
add a protection to not allow running asusd in terminal

Closes #104

See merge request asus-linux/asusctl!64
2021-07-30 00:12:17 +00:00
Luke Jones
dc51120c27 Merge branch 'main' into 'main'
Add G533QR and 513IH to ledmodes

See merge request asus-linux/asusctl!65
2021-07-30 00:11:05 +00:00
pshem
fc4c2c4346 Add support for 513IH led modes 2021-07-24 19:34:09 +01:00
pshem
3f6be037c1 Add G533QR to ledmodes 2021-07-24 14:39:11 +01:00
Luke Jones
0a80c97f02 Update README.md 2021-07-13 04:36:39 +00:00
dragonn
88abafc728 add a protection to not allow running asusd in terminal 2021-07-09 18:40:38 +02:00
Luke Jones
ac880a0363 Merge branch 'fluke/gfx-mode-changes' into 'main'
Fluke/gfx mode changes

See merge request asus-linux/asusctl!63
2021-06-10 21:06:56 +00:00
Luke D. Jones
baebd51d99 Better control of gfx modes 2021-06-11 09:03:50 +12:00
Luke D. Jones
226620eb53 Fix up modes and icons 2021-06-07 19:19:49 +12:00
Luke D. Jones
1b34079d14 Trial of blocking vfio/compute unless in integrated mode 2021-06-07 11:02:21 +12:00
Luke D. Jones
8deeffcdad Minor fix to compute/vfio switch 2021-06-06 21:33:31 +12:00
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
57 changed files with 1500 additions and 692 deletions

View File

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

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

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

View File

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

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

View File

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

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

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

View File

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

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.2"
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

@@ -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 => {

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

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

View File

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

View File

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

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::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();

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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

View 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

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

View File

@@ -39,7 +39,7 @@ impl Sequences {
pub fn iter(&self) -> ActionIterator {
ActionIterator {
actions: &self,
actions: self,
next_idx: 0,
}
}

View File

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

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

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