mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 09:23:19 +01:00
Create rog-platform, refactor rogcc ipc-file handling
- Create new rog-platform crate to manage all i/o in a universal way + kbd-led handling + platform handling (asus-nb-wmi) + hidraw + usbraw - Refactor how ROGCC handles IPC for background open, run-in-bg
This commit is contained in:
@@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased ]
|
||||
### Changed
|
||||
- Create new rog-platform crate to manage all i/o in a universal way
|
||||
+ kbd-led handling (requires kernel patches, TUF specific)
|
||||
+ platform handling (asus-nb-wmi)
|
||||
+ hidraw
|
||||
+ usbraw
|
||||
- Refactor how ROGCC handles IPC for background open, run-in-bg
|
||||
|
||||
## [4.3.4] - 2022-08-03
|
||||
### Bugfix
|
||||
|
||||
157
Cargo.lock
generated
157
Cargo.lock
generated
@@ -119,9 +119,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.6.1"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
|
||||
checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener",
|
||||
@@ -228,9 +228,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.56"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
|
||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -332,9 +332,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
|
||||
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
|
||||
|
||||
[[package]]
|
||||
name = "cache-padded"
|
||||
@@ -435,9 +435,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.4"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948"
|
||||
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
@@ -445,9 +445,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "1.2.2"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
|
||||
checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
|
||||
dependencies = [
|
||||
"cache-padded",
|
||||
]
|
||||
@@ -551,16 +551,15 @@ dependencies = [
|
||||
"rog_anime",
|
||||
"rog_aura",
|
||||
"rog_dbus",
|
||||
"rog_platform",
|
||||
"rog_profiles",
|
||||
"rog_supported",
|
||||
"rusb",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"smol",
|
||||
"sysfs-class",
|
||||
"toml",
|
||||
"udev",
|
||||
"zbus",
|
||||
"zvariant",
|
||||
]
|
||||
@@ -740,7 +739,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
[[package]]
|
||||
name = "eframe"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"dark-light",
|
||||
@@ -761,7 +760,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
"epaint",
|
||||
@@ -772,7 +771,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui-winit"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
@@ -786,7 +785,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui_glow"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
@@ -800,7 +799,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
@@ -865,7 +864,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/emilk/egui#a7012cf8a628d125b211fd164ac12fbb898f316e"
|
||||
source = "git+https://github.com/emilk/egui#7c25a9238e8b899b4d5653db98a583e69b790b17"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"ahash 0.7.6",
|
||||
@@ -888,9 +887,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.2"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
@@ -1038,9 +1037,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.21.2"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "781aa11be58ef14b0cd7326618afcbd9cdb5ba686bdab7193d87cdc322cd7033"
|
||||
checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1086,9 +1085,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glutin_egl_sys"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211"
|
||||
checksum = "68900f84b471f31ea1d1355567eb865a2cf446294f06cef8d653ed7bcf5f013d"
|
||||
dependencies = [
|
||||
"gl_generator",
|
||||
"winapi",
|
||||
@@ -1112,9 +1111,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glutin_glx_sys"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e393c8fc02b807459410429150e9c4faffdb312d59b8c038566173c81991351"
|
||||
checksum = "d93d0575865098580c5b3a423188cd959419912ea60b1e48e8b3b526f6d02468"
|
||||
dependencies = [
|
||||
"gl_generator",
|
||||
"x11-dl",
|
||||
@@ -1219,9 +1218,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
@@ -1266,9 +1265,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
version = "0.2.131"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -1292,9 +1291,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libusb1-sys"
|
||||
version = "0.6.2"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dfab089105aa85a3b492b421bd90d55e6257f00f8447cc3873c44f8206809ce"
|
||||
checksum = "f9d0e2afce4245f2c9a418511e5af8718bcaf2fa408aefb259504d1a9cb25f27"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -1334,9 +1333,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mac-notification-sys"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fff231a88fe2e9985f9d159a2f02986fe46daa0f6af976a0d934be4870cc9d02"
|
||||
checksum = "3e72d50edb17756489e79d52eb146927bec8eba9dd48faadf9ef08bca3791ad5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"dirs-next",
|
||||
@@ -1377,9 +1376,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7"
|
||||
checksum = "8e2e4455be2010e8c5e77f0d10234b30f3a636a5305725609b5a71ad00d22577"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@@ -1718,9 +1717,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.15.0"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1e509cfe7a12db2a90bfa057dfcdbc55a347f5da677c506b53dd099cfec9d"
|
||||
checksum = "07ef1a404ae479dd6906f4fa2c88b3c94028f1284beb42a47c183a7c27ee9a3e"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
@@ -1840,28 +1839,29 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.1.3"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
|
||||
checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.42"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.20"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -1907,9 +1907,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534cfe58d6a18cc17120fbf4635d53d14691c1fe4d951064df9bd326178d7d5a"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
@@ -1985,7 +1985,6 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sysfs-class",
|
||||
"udev",
|
||||
"zbus",
|
||||
"zvariant",
|
||||
]
|
||||
@@ -2013,6 +2012,16 @@ dependencies = [
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rog_platform"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rusb",
|
||||
"sysfs-class",
|
||||
"udev",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rog_profiles"
|
||||
version = "1.1.3"
|
||||
@@ -2057,9 +2066,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.10"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@@ -2084,18 +2093,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.140"
|
||||
version = "1.0.143"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
|
||||
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.140"
|
||||
version = "1.0.143"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
|
||||
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2104,9 +2113,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -2115,9 +2124,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"
|
||||
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2221,7 +2230,7 @@ dependencies = [
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memmap2 0.5.5",
|
||||
"memmap2 0.5.6",
|
||||
"nix 0.24.2",
|
||||
"pkg-config",
|
||||
"wayland-client",
|
||||
@@ -2308,9 +2317,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.98"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2351,18 +2360,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2371,9 +2380,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.11"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
|
||||
checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num_threads",
|
||||
@@ -2415,9 +2424,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
|
||||
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
@@ -2438,9 +2447,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.28"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
|
||||
checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
@@ -2480,9 +2489,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
@@ -2914,9 +2923,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
version = "2.19.1"
|
||||
version = "2.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59"
|
||||
checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace]
|
||||
members = ["asusctl", "asus-notify", "daemon", "daemon-user", "rog-supported", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
||||
members = ["asusctl", "asus-notify", "daemon", "daemon-user", "rog-platform", "rog-supported", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
||||
|
||||
[profile.release]
|
||||
# thin = 57s, asusd = 9.0M
|
||||
|
||||
@@ -774,7 +774,7 @@ fn handle_bios_option(
|
||||
|
||||
for line in usage.iter().filter(|line| {
|
||||
line.contains("sound") && supported.post_sound
|
||||
|| line.contains("GPU") && supported.dedicated_gfx
|
||||
|| line.contains("GPU") && supported.dgpu_only
|
||||
|| line.contains("panel") && supported.panel_overdrive
|
||||
}) {
|
||||
println!("{}", line);
|
||||
@@ -802,7 +802,7 @@ fn handle_bios_option(
|
||||
}
|
||||
}
|
||||
if cmd.dedicated_gfx_get {
|
||||
let res = dbus.proxies().rog_bios().dedicated_graphic_mode()? == 1;
|
||||
let res = dbus.proxies().rog_bios().dedicated_graphic_mode()?;
|
||||
println!("Bios dedicated GPU on: {}", res);
|
||||
}
|
||||
|
||||
@@ -810,7 +810,7 @@ fn handle_bios_option(
|
||||
dbus.proxies().rog_bios().set_panel_overdrive(opt)?;
|
||||
}
|
||||
if cmd.panel_overdrive_get {
|
||||
let res = dbus.proxies().rog_bios().panel_overdrive()? == 1;
|
||||
let res = dbus.proxies().rog_bios().panel_overdrive()?;
|
||||
println!("Panel overdrive on: {}", res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,13 @@ path = "src/daemon.rs"
|
||||
rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
||||
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
||||
rog_supported = { path = "../rog-supported" }
|
||||
rog_platform = { path = "../rog-platform" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
|
||||
async-trait = "^0.1"
|
||||
smol = "^1.2"
|
||||
|
||||
rusb = "^0.9"
|
||||
udev = "^0.6"
|
||||
|
||||
# cli and logging
|
||||
log = "^0.4"
|
||||
env_logger = "^0.9"
|
||||
|
||||
@@ -8,25 +8,21 @@ use logind_zbus::manager::ManagerProxy;
|
||||
use rog_anime::{
|
||||
error::AnimeError,
|
||||
usb::{
|
||||
find_node, get_anime_type, pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on,
|
||||
pkts_for_init, PROD_ID, VENDOR_ID,
|
||||
get_anime_type, pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on,
|
||||
pkts_for_init,
|
||||
},
|
||||
ActionData, AnimeDataBuffer, AnimePacketType, AnimeType,
|
||||
};
|
||||
use rog_platform::{hid_raw::HidRaw, usb_raw::USBRaw};
|
||||
use rog_supported::AnimeSupportedFunctions;
|
||||
use rusb::{Device, DeviceHandle};
|
||||
use smol::{stream::StreamExt, Executor};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
convert::TryFrom,
|
||||
error::Error,
|
||||
sync::{Arc, Mutex, MutexGuard},
|
||||
thread::sleep,
|
||||
};
|
||||
use std::{
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::{error::RogError, GetSupported};
|
||||
|
||||
@@ -36,14 +32,13 @@ impl GetSupported for CtrlAnime {
|
||||
type A = AnimeSupportedFunctions;
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
AnimeSupportedFunctions(CtrlAnime::get_device(VENDOR_ID, PROD_ID).is_ok())
|
||||
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CtrlAnime {
|
||||
_node: String,
|
||||
node: USBRaw,
|
||||
anime_type: AnimeType,
|
||||
handle: RefCell<DeviceHandle<rusb::GlobalContext>>,
|
||||
cache: AnimeConfigCached,
|
||||
config: AnimeConfig,
|
||||
// set to force thread to exit
|
||||
@@ -55,57 +50,26 @@ pub struct CtrlAnime {
|
||||
impl CtrlAnime {
|
||||
#[inline]
|
||||
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, Box<dyn Error>> {
|
||||
let node = find_node("193b")?;
|
||||
let node = USBRaw::new(0x193b)?;
|
||||
let anime_type = get_anime_type()?;
|
||||
let device = Self::get_dev_handle()?;
|
||||
|
||||
info!("Device has an AniMe Matrix display");
|
||||
let mut cache = AnimeConfigCached::default();
|
||||
cache.init_from_config(&config, anime_type)?;
|
||||
|
||||
let ctrl = CtrlAnime {
|
||||
_node: node,
|
||||
node,
|
||||
anime_type,
|
||||
handle: RefCell::new(device),
|
||||
cache,
|
||||
config,
|
||||
thread_exit: Arc::new(AtomicBool::new(false)),
|
||||
thread_running: Arc::new(AtomicBool::new(false)),
|
||||
};
|
||||
ctrl.do_initialization();
|
||||
ctrl.do_initialization()?;
|
||||
|
||||
Ok(ctrl)
|
||||
}
|
||||
|
||||
fn get_dev_handle() -> Result<DeviceHandle<rusb::GlobalContext>, Box<dyn Error>> {
|
||||
// We don't expect this ID to ever change
|
||||
let device = CtrlAnime::get_device(0x0b05, 0x193b)?;
|
||||
|
||||
let mut device = device.open()?;
|
||||
device.reset()?;
|
||||
|
||||
device.set_auto_detach_kernel_driver(true).map_err(|err| {
|
||||
error!("Auto-detach kernel driver failed: {}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
device.claim_interface(0).map_err(|err| {
|
||||
error!("Could not claim device interface: {}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
fn get_device(vendor: u16, product: u16) -> Result<Device<rusb::GlobalContext>, rusb::Error> {
|
||||
for device in rusb::devices()?.iter() {
|
||||
let device_desc = device.device_descriptor()?;
|
||||
if device_desc.vendor_id() == vendor && device_desc.product_id() == product {
|
||||
return Ok(device);
|
||||
}
|
||||
}
|
||||
Err(rusb::Error::NoDevice)
|
||||
}
|
||||
// let device = CtrlAnime::get_device(0x0b05, 0x193b)?;
|
||||
|
||||
/// Start an action thread. This is classed as a singleton and there should be only
|
||||
/// one running - so the thread uses atomics to signal run/exit.
|
||||
@@ -230,45 +194,6 @@ impl CtrlAnime {
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn write_bytes(&self, message: &[u8]) {
|
||||
// if let Ok(mut file) = OpenOptions::new().write(true).open(&self.node) {
|
||||
// println!("write: {:02x?}", &message);
|
||||
// return file
|
||||
// .write_all(message).unwrap();
|
||||
// }
|
||||
let mut error = false;
|
||||
|
||||
match self.handle.borrow().write_control(
|
||||
0x21, // request_type
|
||||
0x09, // request
|
||||
0x35e, // value
|
||||
0x00, // index
|
||||
message,
|
||||
Duration::from_millis(200),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => {
|
||||
error = true;
|
||||
error!("Failed to write to led interrupt: {}", err);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if error {
|
||||
warn!("Will attempt to get AniMe device handle again");
|
||||
match Self::get_dev_handle() {
|
||||
Ok(dev) => {
|
||||
self.handle.replace(dev);
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to get AniMe device: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write only a data packet. This will modify the leds brightness using the
|
||||
/// global brightness set in config.
|
||||
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) -> Result<(), RogError> {
|
||||
@@ -281,16 +206,17 @@ impl CtrlAnime {
|
||||
}
|
||||
let data = AnimePacketType::try_from(buffer)?;
|
||||
for row in data.iter() {
|
||||
self.write_bytes(row);
|
||||
self.node.write_bytes(row)?;
|
||||
}
|
||||
self.write_bytes(&pkt_for_flush());
|
||||
self.node.write_bytes(&pkt_for_flush())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_initialization(&self) {
|
||||
fn do_initialization(&self) -> Result<(), RogError> {
|
||||
let pkts = pkts_for_init();
|
||||
self.write_bytes(&pkts[0]);
|
||||
self.write_bytes(&pkts[1]);
|
||||
self.node.write_bytes(&pkts[0])?;
|
||||
self.node.write_bytes(&pkts[1])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,10 +306,12 @@ pub struct CtrlAnimeReloader(pub Arc<Mutex<CtrlAnime>>);
|
||||
impl crate::Reloadable for CtrlAnimeReloader {
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_on(lock.config.awake_enabled));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
lock.write_bytes(&pkt_for_set_boot(lock.config.boot_anim_enabled));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
lock.node
|
||||
.write_bytes(&pkt_for_set_on(lock.config.awake_enabled))?;
|
||||
lock.node.write_bytes(&pkt_for_apply())?;
|
||||
lock.node
|
||||
.write_bytes(&pkt_for_set_boot(lock.config.boot_anim_enabled))?;
|
||||
lock.node.write_bytes(&pkt_for_apply())?;
|
||||
|
||||
let action = lock.cache.boot.clone();
|
||||
CtrlAnime::run_thread(self.0.clone(), action, true);
|
||||
|
||||
@@ -64,7 +64,12 @@ impl CtrlAnimeZbus {
|
||||
let states;
|
||||
'outer: loop {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_on(status));
|
||||
lock.node
|
||||
.write_bytes(&pkt_for_set_on(status))
|
||||
.map_err(|err| {
|
||||
warn!("rog_anime::run_animation:callback {}", err);
|
||||
})
|
||||
.ok();
|
||||
lock.config.awake_enabled = status;
|
||||
lock.config.write();
|
||||
|
||||
@@ -86,8 +91,18 @@ impl CtrlAnimeZbus {
|
||||
let states;
|
||||
'outer: loop {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_boot(on));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
lock.node
|
||||
.write_bytes(&pkt_for_set_boot(on))
|
||||
.map_err(|err| {
|
||||
warn!("rog_anime::run_animation:callback {}", err);
|
||||
})
|
||||
.ok();
|
||||
lock.node
|
||||
.write_bytes(&pkt_for_apply())
|
||||
.map_err(|err| {
|
||||
warn!("rog_anime::run_animation:callback {}", err);
|
||||
})
|
||||
.ok();
|
||||
lock.config.boot_anim_enabled = on;
|
||||
lock.config.write();
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ use crate::laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||
use log::{error, warn};
|
||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::keyboard_led::KeyboardLed;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use super::controller::CtrlKbdLed;
|
||||
|
||||
pub static AURA_CONFIG_PATH: &str = "/etc/asusd/aura.conf";
|
||||
|
||||
/// Enable/disable LED control in various states such as
|
||||
@@ -128,14 +128,16 @@ impl Default for AuraConfig {
|
||||
fn default() -> Self {
|
||||
let mut prod_id = AuraDevice::Unknown;
|
||||
for prod in ASUS_KEYBOARD_DEVICES.iter() {
|
||||
if let Ok(_) = CtrlKbdLed::find_led_node(prod) {
|
||||
if let Ok(_) = HidRaw::new(prod) {
|
||||
prod_id = AuraDevice::from(*prod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if CtrlKbdLed::get_tuf_mode_path().is_some() {
|
||||
prod_id = AuraDevice::Tuf;
|
||||
if let Ok(p) = KeyboardLed::new() {
|
||||
if p.has_keyboard_rgb_mode() {
|
||||
prod_id = AuraDevice::Tuf;
|
||||
}
|
||||
}
|
||||
|
||||
let enabled = if prod_id == AuraDevice::X19B6 {
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
// Only these two packets must be 17 bytes
|
||||
static KBD_BRIGHT_PATH: &str = "/sys/class/leds/asus::kbd_backlight/brightness";
|
||||
static TUF_RGB_MODE_PATH: &str = "/sys/devices/platform/asus-nb-wmi/tuf_krgb_mode";
|
||||
static TUF_RGB_STATE_PATH: &str = "/sys/devices/platform/asus-nb-wmi/tuf_krgb_state";
|
||||
|
||||
use crate::{
|
||||
error::RogError,
|
||||
laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES},
|
||||
@@ -16,16 +11,13 @@ use rog_aura::{
|
||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||
};
|
||||
use rog_aura::{AuraZone, Direction, Speed, GRADIENT};
|
||||
use rog_platform::{hid_raw::HidRaw, keyboard_led::KeyboardLed};
|
||||
use rog_supported::LedSupportedFunctions;
|
||||
use smol::{stream::StreamExt, Executor};
|
||||
use std::path::Path;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
io::{Read, Write},
|
||||
};
|
||||
use std::{fs::OpenOptions, sync::MutexGuard};
|
||||
use std::sync::MutexGuard;
|
||||
use zbus::Connection;
|
||||
|
||||
use crate::GetSupported;
|
||||
@@ -44,19 +36,21 @@ impl GetSupported for CtrlKbdLed {
|
||||
|
||||
let mut prod_id = AuraDevice::Unknown;
|
||||
for prod in ASUS_KEYBOARD_DEVICES.iter() {
|
||||
if let Ok(_) = Self::find_led_node(prod) {
|
||||
if let Ok(_) = HidRaw::new(prod) {
|
||||
prod_id = AuraDevice::from(*prod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if Self::get_tuf_mode_path().is_some() {
|
||||
prod_id = AuraDevice::Tuf;
|
||||
if let Ok(p) = KeyboardLed::new() {
|
||||
if p.has_keyboard_rgb_mode() {
|
||||
prod_id = AuraDevice::Tuf;
|
||||
}
|
||||
}
|
||||
|
||||
LedSupportedFunctions {
|
||||
prod_id,
|
||||
brightness_set: CtrlKbdLed::get_kbd_bright_path().is_some(),
|
||||
brightness_set: KeyboardLed::new().is_ok(),
|
||||
stock_led_modes,
|
||||
multizone_led_mode,
|
||||
per_key_led_mode,
|
||||
@@ -66,8 +60,8 @@ impl GetSupported for CtrlKbdLed {
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
pub enum LEDNode {
|
||||
Tuf,
|
||||
Rog(String),
|
||||
KbdLed(KeyboardLed),
|
||||
Rog(HidRaw),
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -75,7 +69,7 @@ pub struct CtrlKbdLed {
|
||||
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
||||
pub led_prod: Option<String>,
|
||||
pub led_node: LEDNode,
|
||||
pub bright_node: String,
|
||||
pub kd_brightness: KeyboardLed,
|
||||
pub supported_modes: LaptopLedData,
|
||||
pub flip_effect_write: bool,
|
||||
pub config: AuraConfig,
|
||||
@@ -91,27 +85,11 @@ impl CtrlKbdLedTask {
|
||||
}
|
||||
|
||||
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 Ok(());
|
||||
}
|
||||
Err(RogError::ParseLed)
|
||||
let bright = lock.kd_brightness.get_brightness()?;
|
||||
lock.config.read();
|
||||
lock.config.brightness = (bright as u32).into();
|
||||
lock.config.write();
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,9 +167,7 @@ impl crate::Reloadable for CtrlKbdLedReloader {
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
ctrl.write_current_config_mode()?;
|
||||
ctrl.set_power_states(&ctrl.config)
|
||||
.map_err(|err| warn!("{err}"))
|
||||
.ok();
|
||||
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -210,7 +186,7 @@ impl CtrlKbdLed {
|
||||
let mut led_prod = None;
|
||||
let mut led_node = None;
|
||||
for prod in ASUS_KEYBOARD_DEVICES.iter() {
|
||||
match Self::find_led_node(prod) {
|
||||
match HidRaw::new(prod) {
|
||||
Ok(node) => {
|
||||
led_prod = Some(prod.to_string());
|
||||
led_node = Some(node);
|
||||
@@ -221,10 +197,10 @@ impl CtrlKbdLed {
|
||||
}
|
||||
}
|
||||
|
||||
let bright_node = Self::get_kbd_bright_path();
|
||||
let tuf_node = Self::get_tuf_mode_path().is_some() || Self::get_tuf_state_path().is_some();
|
||||
let bright_node = KeyboardLed::new();
|
||||
let platform = KeyboardLed::new()?;
|
||||
|
||||
if led_node.is_none() && tuf_node && bright_node.is_none() {
|
||||
if led_node.is_none() && !platform.has_keyboard_rgb_mode() {
|
||||
let dmi = sysfs_class::DmiId::default();
|
||||
if let Ok(prod_family) = dmi.product_family() {
|
||||
if prod_family.contains("TUF") {
|
||||
@@ -237,9 +213,9 @@ impl CtrlKbdLed {
|
||||
let led_node = if let Some(rog) = led_node {
|
||||
info!("Found ROG USB keyboard");
|
||||
LEDNode::Rog(rog)
|
||||
} else if tuf_node {
|
||||
} else if platform.has_keyboard_rgb_mode() {
|
||||
info!("Found TUF keyboard");
|
||||
LEDNode::Tuf
|
||||
LEDNode::KbdLed(platform)
|
||||
} else {
|
||||
LEDNode::None
|
||||
};
|
||||
@@ -247,7 +223,7 @@ impl CtrlKbdLed {
|
||||
let ctrl = CtrlKbdLed {
|
||||
led_prod,
|
||||
led_node,
|
||||
bright_node: bright_node.unwrap(), // If was none then we already returned above
|
||||
kd_brightness: bright_node?, // If was none then we already returned above
|
||||
supported_modes,
|
||||
flip_effect_write: false,
|
||||
config,
|
||||
@@ -255,58 +231,16 @@ impl CtrlKbdLed {
|
||||
Ok(ctrl)
|
||||
}
|
||||
|
||||
fn get_kbd_bright_path() -> Option<String> {
|
||||
if Path::new(KBD_BRIGHT_PATH).exists() {
|
||||
return Some(KBD_BRIGHT_PATH.to_string());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_tuf_mode_path() -> Option<String> {
|
||||
if Path::new(TUF_RGB_MODE_PATH).exists() {
|
||||
return Some(TUF_RGB_MODE_PATH.to_string());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn get_tuf_state_path() -> Option<String> {
|
||||
if Path::new(TUF_RGB_STATE_PATH).exists() {
|
||||
return Some(TUF_RGB_STATE_PATH.to_string());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(super) fn get_brightness(&self) -> Result<u8, RogError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&self.bright_node)
|
||||
.map_err(|err| match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
RogError::MissingLedBrightNode((&self.bright_node).into(), err)
|
||||
}
|
||||
_ => RogError::Path((&self.bright_node).into(), err),
|
||||
})?;
|
||||
let mut buf = [0u8; 1];
|
||||
file.read_exact(&mut buf)
|
||||
.map_err(|err| RogError::Read("buffer".into(), err))?;
|
||||
Ok(buf[0])
|
||||
self.kd_brightness
|
||||
.get_brightness()
|
||||
.map_err(|e| RogError::Platform(e))
|
||||
}
|
||||
|
||||
pub(super) fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
|
||||
let path = Path::new(&self.bright_node);
|
||||
let mut file =
|
||||
OpenOptions::new()
|
||||
.write(true)
|
||||
.open(&path)
|
||||
.map_err(|err| match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
RogError::MissingLedBrightNode((&self.bright_node).into(), err)
|
||||
}
|
||||
_ => RogError::Path((&self.bright_node).into(), err),
|
||||
})?;
|
||||
file.write_all(&[brightness.as_char_code()])
|
||||
.map_err(|err| RogError::Read("buffer".into(), err))?;
|
||||
Ok(())
|
||||
self.kd_brightness
|
||||
.set_brightness(brightness.as_char_code())
|
||||
.map_err(|e| RogError::Platform(e))
|
||||
}
|
||||
|
||||
pub fn next_brightness(&mut self) -> Result<(), RogError> {
|
||||
@@ -332,68 +266,24 @@ impl CtrlKbdLed {
|
||||
}
|
||||
|
||||
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
|
||||
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
|
||||
if LEDNode::Tuf == self.led_node {
|
||||
if let Some(path) = Self::get_tuf_state_path() {
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
if let Some(pwr) = AuraPowerConfig::to_tuf_bool_array(&config.enabled) {
|
||||
let buf = format!(
|
||||
"1 {} {} {} {}",
|
||||
pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, pwr[4] as u8,
|
||||
);
|
||||
file.write_all(buf.as_bytes())?;
|
||||
}
|
||||
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
||||
if let LEDNode::KbdLed(platform) = &mut self.led_node {
|
||||
if let Some(pwr) = AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
|
||||
let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, pwr[4] as u8];
|
||||
platform.set_keyboard_rgb_state(&buf)?;
|
||||
}
|
||||
} else {
|
||||
let bytes = AuraPowerConfig::to_bytes(&config.enabled);
|
||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
let bytes = AuraPowerConfig::to_bytes(&self.config.enabled);
|
||||
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2]];
|
||||
|
||||
self.write_bytes(&message)?;
|
||||
self.write_bytes(&LED_SET)?;
|
||||
hid_raw.write_bytes(&message)?;
|
||||
hid_raw.write_bytes(&LED_SET)?;
|
||||
// Changes won't persist unless apply is set
|
||||
self.write_bytes(&LED_APPLY)?;
|
||||
hid_raw.write_bytes(&LED_APPLY)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn find_led_node(id_product: &str) -> Result<String, RogError> {
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
RogError::Udev("enumerator failed".into(), err)
|
||||
})?;
|
||||
enumerator.match_subsystem("hidraw").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
RogError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
for device in enumerator.scan_devices().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
RogError::Udev("scan_devices failed".into(), err)
|
||||
})? {
|
||||
if let Some(parent) = device
|
||||
.parent_with_subsystem_devtype("usb", "usb_device")
|
||||
.map_err(|err| {
|
||||
warn!("{}", err);
|
||||
RogError::Udev("parent_with_subsystem_devtype failed".into(), err)
|
||||
})?
|
||||
{
|
||||
if parent
|
||||
.attribute_value("idProduct")
|
||||
.ok_or_else(|| RogError::NotFound("LED idProduct".into()))?
|
||||
== id_product
|
||||
{
|
||||
if let Some(dev_node) = device.devnode() {
|
||||
info!("Using device at: {:?} for LED control", dev_node);
|
||||
return Ok(dev_node.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(RogError::MissingFunction(
|
||||
"ASUS LED device node not found".into(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Set an Aura effect if the effect mode or zone is supported.
|
||||
///
|
||||
/// On success the aura config file is read to refresh cached values, then the effect is
|
||||
@@ -414,28 +304,17 @@ impl CtrlKbdLed {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Should only be used if the bytes you are writing are verified correct
|
||||
fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
||||
if let LEDNode::Rog(led_node) = &self.led_node {
|
||||
if let Ok(mut file) = OpenOptions::new().write(true).open(led_node) {
|
||||
// println!("write: {:02x?}", &message);
|
||||
return file
|
||||
.write_all(message)
|
||||
.map_err(|err| RogError::Write("write_bytes".into(), err));
|
||||
}
|
||||
}
|
||||
Err(RogError::NoAuraNode)
|
||||
}
|
||||
|
||||
/// Write an effect block. This is for per-key
|
||||
fn _write_effect(&mut self, effect: &[Vec<u8>]) -> Result<(), RogError> {
|
||||
if self.flip_effect_write {
|
||||
for row in effect.iter().rev() {
|
||||
self.write_bytes(row)?;
|
||||
}
|
||||
} else {
|
||||
for row in effect.iter() {
|
||||
self.write_bytes(row)?;
|
||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
if self.flip_effect_write {
|
||||
for row in effect.iter().rev() {
|
||||
hid_raw.write_bytes(row)?;
|
||||
}
|
||||
} else {
|
||||
for row in effect.iter() {
|
||||
hid_raw.write_bytes(row)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.flip_effect_write = !self.flip_effect_write;
|
||||
@@ -478,19 +357,24 @@ impl CtrlKbdLed {
|
||||
}
|
||||
|
||||
fn write_mode(&self, mode: &AuraEffect) -> Result<(), RogError> {
|
||||
if LEDNode::Tuf == self.led_node {
|
||||
let mut file = OpenOptions::new().write(true).open(TUF_RGB_MODE_PATH)?;
|
||||
let buf = format!(
|
||||
"1 {} {} {} {} {}",
|
||||
mode.mode as u8, mode.colour1.0, mode.colour1.1, mode.colour1.2, mode.speed as u8,
|
||||
);
|
||||
file.write_all(buf.as_bytes())?;
|
||||
} else {
|
||||
if let LEDNode::KbdLed(platform) = &self.led_node {
|
||||
let buf = [
|
||||
1,
|
||||
mode.mode as u8,
|
||||
mode.colour1.0,
|
||||
mode.colour1.1,
|
||||
mode.colour1.2,
|
||||
mode.speed as u8,
|
||||
];
|
||||
platform.set_keyboard_rgb_mode(&buf)?;
|
||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||
self.write_bytes(&bytes)?;
|
||||
self.write_bytes(&LED_SET)?;
|
||||
hid_raw.write_bytes(&bytes)?;
|
||||
hid_raw.write_bytes(&LED_SET)?;
|
||||
// Changes won't persist unless apply is set
|
||||
self.write_bytes(&LED_APPLY)?;
|
||||
hid_raw.write_bytes(&LED_APPLY)?;
|
||||
} else {
|
||||
return Err(RogError::NoAuraKeyboard);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -562,6 +446,7 @@ impl CtrlKbdLed {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||
use rog_platform::keyboard_led::KeyboardLed;
|
||||
|
||||
use crate::{
|
||||
ctrl_aura::{config::AuraConfig, controller::LEDNode},
|
||||
@@ -585,7 +470,7 @@ mod tests {
|
||||
let mut controller = CtrlKbdLed {
|
||||
led_prod: None,
|
||||
led_node: LEDNode::None,
|
||||
bright_node: String::new(),
|
||||
kd_brightness: KeyboardLed::default(),
|
||||
supported_modes,
|
||||
flip_effect_write: false,
|
||||
config,
|
||||
@@ -601,7 +486,7 @@ mod tests {
|
||||
.set_effect(effect.clone())
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"No Aura keyboard node found"
|
||||
"No supported Aura keyboard"
|
||||
);
|
||||
|
||||
effect.mode = AuraModeNum::Laser;
|
||||
@@ -629,7 +514,7 @@ mod tests {
|
||||
.set_effect(effect.clone())
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"No Aura keyboard node found"
|
||||
"No supported Aura keyboard"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -647,7 +532,7 @@ mod tests {
|
||||
let mut controller = CtrlKbdLed {
|
||||
led_prod: None,
|
||||
led_node: LEDNode::None,
|
||||
bright_node: String::new(),
|
||||
kd_brightness: KeyboardLed::default(),
|
||||
supported_modes,
|
||||
flip_effect_write: false,
|
||||
config,
|
||||
@@ -684,7 +569,7 @@ mod tests {
|
||||
let mut controller = CtrlKbdLed {
|
||||
led_prod: None,
|
||||
led_node: LEDNode::None,
|
||||
bright_node: String::new(),
|
||||
kd_brightness: KeyboardLed::default(),
|
||||
supported_modes,
|
||||
flip_effect_write: false,
|
||||
config,
|
||||
@@ -699,7 +584,7 @@ mod tests {
|
||||
.write_current_config_mode()
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
"No Aura keyboard node found"
|
||||
"No supported Aura keyboard"
|
||||
);
|
||||
assert!(controller.config.multizone.is_some());
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ impl CtrlKbdLedZbus {
|
||||
|
||||
ctrl.config.write();
|
||||
|
||||
ctrl.set_power_states(&ctrl.config).map_err(|e| {
|
||||
ctrl.set_power_states().map_err(|e| {
|
||||
warn!("{}", e);
|
||||
e
|
||||
})?;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{config::Config, error::RogError, GetSupported};
|
||||
use async_trait::async_trait;
|
||||
use log::{error, info, warn};
|
||||
use rog_platform::platform::AsusPlatform;
|
||||
use rog_supported::RogBiosSupportedFunctions;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufRead;
|
||||
@@ -15,15 +16,13 @@ use zbus::{dbus_interface, SignalContext};
|
||||
const INITRAMFS_PATH: &str = "/usr/sbin/update-initramfs";
|
||||
const DRACUT_PATH: &str = "/usr/bin/dracut";
|
||||
|
||||
static ASUS_SWITCH_GRAPHIC_MODE: &str =
|
||||
"/sys/firmware/efi/efivars/AsusSwitchGraphicMode-607005d5-3f75-4b2e-98f0-85ba66797a3e";
|
||||
// static ASUS_SWITCH_GRAPHIC_MODE: &str =
|
||||
// "/sys/firmware/efi/efivars/AsusSwitchGraphicMode-607005d5-3f75-4b2e-98f0-85ba66797a3e";
|
||||
static ASUS_POST_LOGO_SOUND: &str =
|
||||
"/sys/firmware/efi/efivars/AsusPostLogoSound-607005d5-3f75-4b2e-98f0-85ba66797a3e";
|
||||
static ASUS_PANEL_OD_PATH: &str = "/sys/devices/platform/asus-nb-wmi/panel_od";
|
||||
static ASUS_DGPU_DISABLE_PATH: &str = "/sys/devices/platform/asus-nb-wmi/dgpu_disable";
|
||||
static ASUS_EGPU_ENABLE_PATH: &str = "/sys/devices/platform/asus-nb-wmi/egpu_enable";
|
||||
|
||||
pub struct CtrlRogBios {
|
||||
platform: AsusPlatform,
|
||||
_config: Arc<Mutex<Config>>,
|
||||
}
|
||||
|
||||
@@ -31,12 +30,24 @@ impl GetSupported for CtrlRogBios {
|
||||
type A = RogBiosSupportedFunctions;
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
let mut panel_overdrive = false;
|
||||
let mut dgpu_disable = false;
|
||||
let mut egpu_enable = false;
|
||||
let mut dgpu_only = false;
|
||||
|
||||
if let Ok(platform) = AsusPlatform::new() {
|
||||
panel_overdrive = platform.has_panel_od();
|
||||
dgpu_disable = platform.has_dgpu_disable();
|
||||
egpu_enable = platform.has_egpu_enable();
|
||||
dgpu_only = platform.has_gpu_mux_mode();
|
||||
}
|
||||
|
||||
RogBiosSupportedFunctions {
|
||||
post_sound: Path::new(ASUS_POST_LOGO_SOUND).exists(),
|
||||
dedicated_gfx: Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists(),
|
||||
panel_overdrive: Path::new(ASUS_PANEL_OD_PATH).exists(),
|
||||
dgpu_disable: Path::new(ASUS_DGPU_DISABLE_PATH).exists(),
|
||||
egpu_enable: Path::new(ASUS_EGPU_ENABLE_PATH).exists(),
|
||||
dgpu_only,
|
||||
panel_overdrive,
|
||||
dgpu_disable,
|
||||
egpu_enable,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,13 +70,14 @@ impl CtrlRogBios {
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn dedicated_graphic_mode(&self) -> i8 {
|
||||
Self::get_gfx_mode()
|
||||
fn dedicated_graphic_mode(&self) -> bool {
|
||||
self.platform
|
||||
.get_gpu_mux_mode()
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: get_gfx_mode {}", err);
|
||||
err
|
||||
})
|
||||
.unwrap_or(-1)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
@@ -118,26 +130,14 @@ impl CtrlRogBios {
|
||||
}
|
||||
}
|
||||
|
||||
fn panel_overdrive(&self) -> i8 {
|
||||
let path = ASUS_PANEL_OD_PATH;
|
||||
if let Ok(mut file) = OpenOptions::new().read(true).open(path).map_err(|err| {
|
||||
warn!("CtrlRogBios: panel_overdrive {}", err);
|
||||
err
|
||||
}) {
|
||||
let mut buf = Vec::new();
|
||||
file.read_to_end(&mut buf)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: set_panel_overdrive {}", err);
|
||||
err
|
||||
})
|
||||
.ok();
|
||||
|
||||
if buf.len() >= 1 {
|
||||
let tmp = String::from_utf8_lossy(&buf[0..1]);
|
||||
return tmp.parse::<i8>().unwrap_or(-1);
|
||||
}
|
||||
}
|
||||
-1
|
||||
fn panel_overdrive(&self) -> bool {
|
||||
self.platform
|
||||
.get_panel_od()
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: get panel overdrive {}", err);
|
||||
err
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
@@ -163,9 +163,8 @@ impl crate::Reloadable for CtrlRogBios {
|
||||
|
||||
impl CtrlRogBios {
|
||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||
if Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists() {
|
||||
CtrlRogBios::set_path_mutable(ASUS_SWITCH_GRAPHIC_MODE)?;
|
||||
} else {
|
||||
let platform = AsusPlatform::new()?;
|
||||
if !platform.has_gpu_mux_mode() {
|
||||
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.");
|
||||
}
|
||||
@@ -176,7 +175,10 @@ impl CtrlRogBios {
|
||||
info!("Switch for POST boot sound not detected");
|
||||
}
|
||||
|
||||
Ok(CtrlRogBios { _config: config })
|
||||
Ok(CtrlRogBios {
|
||||
platform,
|
||||
_config: config,
|
||||
})
|
||||
}
|
||||
|
||||
fn set_path_mutable(path: &str) -> Result<(), RogError> {
|
||||
@@ -189,48 +191,14 @@ impl CtrlRogBios {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn has_dedicated_gfx_toggle() -> bool {
|
||||
Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists()
|
||||
}
|
||||
|
||||
pub fn get_gfx_mode() -> Result<i8, RogError> {
|
||||
let path = ASUS_SWITCH_GRAPHIC_MODE;
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(path)
|
||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
||||
|
||||
let mut data = Vec::new();
|
||||
file.read_to_end(&mut data)
|
||||
.map_err(|err| RogError::Read(path.into(), err))?;
|
||||
|
||||
let idx = data.len() - 1;
|
||||
Ok(data[idx] as i8)
|
||||
}
|
||||
|
||||
pub(super) fn set_gfx_mode(&self, dedicated: bool) -> Result<(), RogError> {
|
||||
let path = ASUS_SWITCH_GRAPHIC_MODE;
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(path)
|
||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
||||
|
||||
let mut data = Vec::new();
|
||||
file.read_to_end(&mut data)?;
|
||||
|
||||
let idx = data.len() - 1;
|
||||
if dedicated {
|
||||
data[idx] = 1;
|
||||
pub(super) fn set_gfx_mode(&self, enable: bool) -> Result<(), RogError> {
|
||||
self.platform.set_gpu_mux_mode(enable)?;
|
||||
self.update_initramfs(enable)?;
|
||||
if enable {
|
||||
info!("Set system-level graphics mode: Dedicated Nvidia");
|
||||
} else {
|
||||
data[idx] = 0;
|
||||
info!("Set system-level graphics mode: Optimus");
|
||||
}
|
||||
file.write_all(&data)
|
||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
||||
|
||||
self.update_initramfs(dedicated)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -358,42 +326,11 @@ impl CtrlRogBios {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_panel_od(&mut self, overdrive: bool) -> Result<(), RogError> {
|
||||
let path = ASUS_PANEL_OD_PATH;
|
||||
let mut file = OpenOptions::new().write(true).open(path).map_err(|err| {
|
||||
warn!("CtrlRogBios: set_panel_overdrive {}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
let s = if overdrive { '1' } else { '0' };
|
||||
file.write(&[s as u8]).map_err(|err| {
|
||||
fn set_panel_od(&mut self, enable: bool) -> Result<(), RogError> {
|
||||
self.platform.set_panel_od(enable).map_err(|err| {
|
||||
warn!("CtrlRogBios: set_panel_overdrive {}", err);
|
||||
err
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CtrlRogBios;
|
||||
use crate::config::Config;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[test]
|
||||
#[ignore = "Must be manually tested"]
|
||||
fn set_multizone_4key_config() {
|
||||
let config = Config::default();
|
||||
|
||||
let controller = CtrlRogBios {
|
||||
_config: Arc::new(Mutex::new(config)),
|
||||
};
|
||||
|
||||
let res = controller.panel_overdrive();
|
||||
assert_eq!(res, 1);
|
||||
|
||||
// controller.set_panel_od(false).unwrap();
|
||||
// let res = controller.panel_overdrive();
|
||||
// assert_eq!(res, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use rog_anime::error::AnimeError;
|
||||
use rog_platform::error::PlatformError;
|
||||
use rog_profiles::error::ProfileError;
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
@@ -28,6 +29,7 @@ pub enum RogError {
|
||||
NoAuraKeyboard,
|
||||
NoAuraNode,
|
||||
Anime(AnimeError),
|
||||
Platform(PlatformError),
|
||||
}
|
||||
|
||||
impl fmt::Display for RogError {
|
||||
@@ -57,6 +59,7 @@ impl fmt::Display for RogError {
|
||||
RogError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
|
||||
RogError::NoAuraNode => write!(f, "No Aura keyboard node found"),
|
||||
RogError::Anime(deets) => write!(f, "AniMe Matrix error: {}", deets),
|
||||
RogError::Platform(deets) => write!(f, "Asus Platform error: {}", deets),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,6 +78,12 @@ impl From<AnimeError> for RogError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PlatformError> for RogError {
|
||||
fn from(err: PlatformError) -> Self {
|
||||
RogError::Platform(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<zbus::Error> for RogError {
|
||||
fn from(err: zbus::Error) -> Self {
|
||||
RogError::Zbus(err)
|
||||
|
||||
@@ -15,7 +15,7 @@ exclude = ["data"]
|
||||
[features]
|
||||
default = ["dbus", "detect"]
|
||||
dbus = ["zvariant", "zbus"]
|
||||
detect = ["udev", "sysfs-class"]
|
||||
detect = ["sysfs-class"]
|
||||
|
||||
[dependencies]
|
||||
png_pong = "^0.8.0"
|
||||
@@ -31,5 +31,4 @@ glam = { version = "^0.21.2", features = ["serde"] }
|
||||
zvariant = { version = "^3.0", optional = true }
|
||||
zbus = { version = "^2.2", optional = true }
|
||||
|
||||
udev = { version = "^0.6", optional = true }
|
||||
sysfs-class = { version = "^0.1", optional = true }
|
||||
@@ -36,30 +36,6 @@ pub fn get_anime_type() -> Result<AnimeType, AnimeError> {
|
||||
Err(AnimeError::UnsupportedDevice)
|
||||
}
|
||||
|
||||
/// Find the USB device node - known devices so far: `19b6`
|
||||
#[inline]
|
||||
pub fn find_node(id_product: &str) -> Result<String, AnimeError> {
|
||||
let mut enumerator =
|
||||
udev::Enumerator::new().map_err(|err| AnimeError::Udev("enumerator failed".into(), err))?;
|
||||
enumerator
|
||||
.match_subsystem("usb")
|
||||
.map_err(|err| AnimeError::Udev("match_subsystem failed".into(), err))?;
|
||||
|
||||
for device in enumerator
|
||||
.scan_devices()
|
||||
.map_err(|err| AnimeError::Udev("scan_devices failed".into(), err))?
|
||||
{
|
||||
if let Some(attr) = device.attribute_value("idProduct") {
|
||||
if attr == id_product {
|
||||
if let Some(dev_node) = device.devnode() {
|
||||
return Ok(dev_node.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(AnimeError::NoDevice)
|
||||
}
|
||||
|
||||
/// Get the two device initialization packets. These are required for device start
|
||||
/// after the laptop boots.
|
||||
#[inline]
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{error::Error, keys::Key};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs::OpenOptions, io::Read, path::Path, slice::Iter};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct KeyLayout {
|
||||
/// A series of board names that this layout can be used for. The board names
|
||||
/// stored with the layout can be globbed, e.g, GA401 will match all of the
|
||||
@@ -48,7 +48,7 @@ impl KeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct KeyRow {
|
||||
height: f32,
|
||||
row: Vec<Key>,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::{
|
||||
f64::consts::PI,
|
||||
io::Write,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicU8, Ordering},
|
||||
Arc,
|
||||
@@ -12,18 +11,13 @@ use egui::{Button, RichText};
|
||||
use rog_supported::SupportedFunctions;
|
||||
|
||||
use crate::{
|
||||
config::Config, error::Result, get_ipc_file, page_states::PageDataStates, Page,
|
||||
RogDbusClientBlocking, SHOWING_GUI,
|
||||
config::Config, error::Result, page_states::PageDataStates, Page, RogDbusClientBlocking,
|
||||
};
|
||||
|
||||
pub struct RogApp<'a> {
|
||||
pub page: Page,
|
||||
pub states: PageDataStates,
|
||||
pub supported: SupportedFunctions,
|
||||
/// Should the app begin showing the GUI
|
||||
pub begin_show_gui: Arc<AtomicBool>,
|
||||
/// Is the app GUI closed (and running in bg)
|
||||
pub running_in_bg: bool,
|
||||
// TODO: can probably just open and read whenever
|
||||
pub config: Config,
|
||||
pub asus_dbus: RogDbusClientBlocking<'a>,
|
||||
@@ -40,9 +34,7 @@ pub struct RogApp<'a> {
|
||||
impl<'a> RogApp<'a> {
|
||||
/// Called once before the first frame.
|
||||
pub fn new(
|
||||
start_closed: bool,
|
||||
config: Config,
|
||||
show_gui: Arc<AtomicBool>,
|
||||
states: PageDataStates,
|
||||
_cc: &eframe::CreationContext<'_>,
|
||||
) -> Result<Self> {
|
||||
@@ -99,8 +91,6 @@ impl<'a> RogApp<'a> {
|
||||
supported,
|
||||
states,
|
||||
page: Page::System,
|
||||
begin_show_gui: show_gui,
|
||||
running_in_bg: start_closed,
|
||||
config,
|
||||
asus_dbus: dbus,
|
||||
oscillator1,
|
||||
@@ -113,20 +103,10 @@ impl<'a> RogApp<'a> {
|
||||
}
|
||||
|
||||
impl<'a> eframe::App for RogApp<'a> {
|
||||
fn on_exit_event(&mut self) -> bool {
|
||||
if self.config.run_in_background {
|
||||
self.running_in_bg = true;
|
||||
get_ipc_file().unwrap().write_all(&[0]).unwrap();
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Called each time the UI needs repainting, which may be many times per second.
|
||||
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||
let Self {
|
||||
begin_show_gui: should_show_gui,
|
||||
supported,
|
||||
asus_dbus: dbus,
|
||||
states,
|
||||
@@ -144,21 +124,6 @@ impl<'a> eframe::App for RogApp<'a> {
|
||||
|
||||
let page = self.page;
|
||||
|
||||
if should_show_gui.load(Ordering::SeqCst) {
|
||||
let mut ipc_file = get_ipc_file().unwrap();
|
||||
ipc_file.write_all(&[SHOWING_GUI]).unwrap();
|
||||
should_show_gui.store(false, Ordering::SeqCst);
|
||||
frame.set_visible(true);
|
||||
self.running_in_bg = false;
|
||||
}
|
||||
if self.running_in_bg {
|
||||
// Request to draw nothing at all
|
||||
ctx.request_repaint_after(Duration::from_millis(500));
|
||||
frame.set_visible(false);
|
||||
return;
|
||||
}
|
||||
// Do all GUI display after this point
|
||||
|
||||
self.top_bar(ctx, frame);
|
||||
self.side_panel(ctx);
|
||||
|
||||
|
||||
@@ -44,6 +44,14 @@ pub fn on_tmp_dir_exists() -> Result<TempDir, std::io::Error> {
|
||||
let mut buf = [0u8; 4];
|
||||
let path = std::env::temp_dir().join("rog-gui");
|
||||
|
||||
if path.read_dir()?.next().is_none() {
|
||||
std::fs::remove_dir_all(path)?;
|
||||
return tempfile::Builder::new()
|
||||
.prefix("rog-gui")
|
||||
.rand_bytes(0)
|
||||
.tempdir();
|
||||
}
|
||||
|
||||
let mut ipc_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
|
||||
@@ -2,19 +2,14 @@ use rog_aura::layouts::KeyLayout;
|
||||
use rog_control_center::{
|
||||
config::Config, get_ipc_file, notify::start_notifications, on_tmp_dir_exists,
|
||||
page_states::PageDataStates, startup_error::AppErrorShow, RogApp, RogDbusClientBlocking,
|
||||
SHOW_GUI,
|
||||
SHOWING_GUI, SHOW_GUI,
|
||||
};
|
||||
|
||||
use std::{
|
||||
fs::{self, OpenOptions},
|
||||
io::Read,
|
||||
io::{Read, Write},
|
||||
path::PathBuf,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
thread::spawn,
|
||||
time::Duration,
|
||||
sync::{atomic::AtomicBool, Arc},
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
@@ -29,6 +24,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
transparent: false,
|
||||
min_window_size: Some(egui::vec2(840.0, 600.0)),
|
||||
max_window_size: Some(egui::vec2(840.0, 600.0)),
|
||||
run_and_return: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -44,7 +40,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// Startup
|
||||
let mut config = Config::load()?;
|
||||
let start_closed = config.startup_in_background;
|
||||
let mut start_closed = config.startup_in_background;
|
||||
|
||||
if config.startup_in_background {
|
||||
config.run_in_background = true;
|
||||
@@ -94,44 +90,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let fans_notified = Arc::new(AtomicBool::new(false));
|
||||
let notifs_enabled = Arc::new(AtomicBool::new(config.enable_notifications));
|
||||
|
||||
let states = {
|
||||
let supported = dbus
|
||||
.proxies()
|
||||
.supported()
|
||||
.supported_functions()
|
||||
.map_err(|e| {
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
PageDataStates::new(
|
||||
layout,
|
||||
notifs_enabled.clone(),
|
||||
charge_notified.clone(),
|
||||
bios_notified.clone(),
|
||||
aura_notified.clone(),
|
||||
anime_notified.clone(),
|
||||
profiles_notified.clone(),
|
||||
fans_notified.clone(),
|
||||
&supported,
|
||||
&dbus,
|
||||
)? // TODO: if error, show alt GUI containing the error message
|
||||
};
|
||||
|
||||
if config.enable_notifications {
|
||||
start_notifications(
|
||||
charge_notified,
|
||||
bios_notified,
|
||||
aura_notified,
|
||||
anime_notified,
|
||||
profiles_notified,
|
||||
fans_notified,
|
||||
notifs_enabled,
|
||||
)?;
|
||||
}
|
||||
start_notifications(
|
||||
charge_notified.clone(),
|
||||
bios_notified.clone(),
|
||||
aura_notified.clone(),
|
||||
anime_notified.clone(),
|
||||
profiles_notified.clone(),
|
||||
fans_notified.clone(),
|
||||
notifs_enabled.clone(),
|
||||
)?;
|
||||
|
||||
// tmp-dir must live to the end of program life
|
||||
let _tmp_dir = match tempfile::Builder::new()
|
||||
@@ -143,25 +110,59 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Err(_) => on_tmp_dir_exists().unwrap(),
|
||||
};
|
||||
|
||||
let should_show_gui = Arc::new(AtomicBool::new(!start_closed));
|
||||
let should = should_show_gui.clone();
|
||||
spawn(move || {
|
||||
// Loop is blocked here until a single byte is read
|
||||
loop {
|
||||
let mut buf = [0u8; 4];
|
||||
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
||||
should_show_gui.store(true, Ordering::SeqCst);
|
||||
// Give the starting app a change to read or we'll race it
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
});
|
||||
loop {
|
||||
let states = {
|
||||
let supported = match dbus.proxies().supported().supported_functions() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options,
|
||||
Box::new(move |cc| {
|
||||
Box::new(RogApp::new(start_closed, config, should, states, cc).unwrap())
|
||||
}),
|
||||
);
|
||||
PageDataStates::new(
|
||||
layout.clone(),
|
||||
notifs_enabled.clone(),
|
||||
charge_notified.clone(),
|
||||
bios_notified.clone(),
|
||||
aura_notified.clone(),
|
||||
anime_notified.clone(),
|
||||
profiles_notified.clone(),
|
||||
fans_notified.clone(),
|
||||
&supported,
|
||||
&dbus,
|
||||
)?
|
||||
};
|
||||
|
||||
if !start_closed {
|
||||
let mut ipc_file = get_ipc_file().unwrap();
|
||||
ipc_file.write_all(&[SHOWING_GUI]).unwrap();
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |cc| {
|
||||
Box::new(RogApp::new(Config::load().unwrap(), states, cc).unwrap())
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
let config = Config::load().unwrap();
|
||||
if !config.run_in_background {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut buf = [0u8; 4];
|
||||
// blocks until it is read, typically the read will happen after a second
|
||||
// process writes to the IPC (so there is data to actually read)
|
||||
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
||||
start_closed = false;
|
||||
continue;
|
||||
}
|
||||
dbg!("asda");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -39,13 +39,13 @@ impl BiosState {
|
||||
} else {
|
||||
false
|
||||
},
|
||||
dedicated_gfx: if supported.rog_bios_ctrl.dedicated_gfx {
|
||||
dbus.proxies().rog_bios().dedicated_graphic_mode()? != 0
|
||||
dedicated_gfx: if supported.rog_bios_ctrl.dgpu_only {
|
||||
dbus.proxies().rog_bios().dedicated_graphic_mode()?
|
||||
} else {
|
||||
false
|
||||
},
|
||||
panel_overdrive: if supported.rog_bios_ctrl.panel_overdrive {
|
||||
dbus.proxies().rog_bios().panel_overdrive()? != 0
|
||||
dbus.proxies().rog_bios().panel_overdrive()?
|
||||
} else {
|
||||
false
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{sync::atomic::Ordering, time::Duration};
|
||||
|
||||
use egui::Color32;
|
||||
use rog_aura::AuraModeNum;
|
||||
use rog_aura::{AuraEffect, AuraModeNum};
|
||||
|
||||
use crate::{
|
||||
widgets::{aura_modes_group, keyboard},
|
||||
@@ -31,14 +31,14 @@ impl<'a> RogApp<'a> {
|
||||
.aura
|
||||
.modes
|
||||
.get(&states.aura.current_mode)
|
||||
.unwrap()
|
||||
.unwrap_or(&AuraEffect::default())
|
||||
.colour1;
|
||||
|
||||
let c2 = states
|
||||
.aura
|
||||
.modes
|
||||
.get(&states.aura.current_mode)
|
||||
.unwrap()
|
||||
.unwrap_or(&AuraEffect::default())
|
||||
.colour2;
|
||||
|
||||
let mut colour = Color32::from_rgb(c1.0, c1.1, c1.2);
|
||||
|
||||
@@ -16,20 +16,21 @@ pub fn fan_graphs(
|
||||
ui.separator();
|
||||
|
||||
let mut item = |p: Profile, ui: &mut Ui| {
|
||||
ui.group(|ui|{
|
||||
ui.selectable_value(&mut curves.show_curve, p, format!("{p:?}"));
|
||||
ui.add_enabled_ui(curves.show_curve == p ,|ui| {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
});});
|
||||
ui.group(|ui| {
|
||||
ui.selectable_value(&mut curves.show_curve, p, format!("{p:?}"));
|
||||
ui.add_enabled_ui(curves.show_curve == p, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
|
||||
@@ -90,7 +90,7 @@ pub fn rog_bios_group(
|
||||
}
|
||||
}
|
||||
|
||||
if supported.rog_bios_ctrl.dedicated_gfx {
|
||||
if supported.rog_bios_ctrl.dgpu_only {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(
|
||||
&mut states.bios.dedicated_gfx,
|
||||
|
||||
@@ -27,7 +27,7 @@ use zbus_macros::dbus_proxy;
|
||||
)]
|
||||
trait RogBios {
|
||||
/// DedicatedGraphicMode method
|
||||
fn dedicated_graphic_mode(&self) -> zbus::Result<i16>;
|
||||
fn dedicated_graphic_mode(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// PostBootSound method
|
||||
fn post_boot_sound(&self) -> zbus::Result<i16>;
|
||||
@@ -39,7 +39,7 @@ trait RogBios {
|
||||
fn set_post_boot_sound(&self, on: bool) -> zbus::Result<()>;
|
||||
|
||||
/// PanelOverdrive method
|
||||
fn panel_overdrive(&self) -> zbus::Result<i8>;
|
||||
fn panel_overdrive(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// SetPanelOverdrive method
|
||||
fn set_panel_overdrive(&self, overdrive: bool) -> zbus::Result<()>;
|
||||
|
||||
12
rog-platform/Cargo.toml
Normal file
12
rog-platform/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "rog_platform"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "*"
|
||||
udev = "^0.6"
|
||||
rusb = "^0.9"
|
||||
sysfs-class = "^0.1"
|
||||
51
rog-platform/src/error.rs
Normal file
51
rog-platform/src/error.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use std::fmt;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, PlatformError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PlatformError {
|
||||
ParseVendor,
|
||||
ParseNum,
|
||||
Udev(String, std::io::Error),
|
||||
USB(rusb::Error),
|
||||
Path(String, std::io::Error),
|
||||
Read(String, std::io::Error),
|
||||
Write(String, std::io::Error),
|
||||
NotSupported,
|
||||
AttrNotFound(String),
|
||||
MissingFunction(String),
|
||||
MissingLedBrightNode(String, std::io::Error),
|
||||
Io(String, std::io::Error),
|
||||
NoAuraKeyboard,
|
||||
NoAuraNode,
|
||||
}
|
||||
|
||||
impl fmt::Display for PlatformError {
|
||||
// This trait requires `fmt` with this exact signature.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
PlatformError::ParseVendor => write!(f, "Parse gfx vendor error"),
|
||||
PlatformError::ParseNum => write!(f, "Parse number error"),
|
||||
PlatformError::Udev(deets, error) => write!(f, "udev {}: {}", deets, error),
|
||||
PlatformError::USB(error) => write!(f, "usb {}", error),
|
||||
PlatformError::Path(path, error) => write!(f, "Path {}: {}", path, error),
|
||||
PlatformError::Read(path, error) => write!(f, "Read {}: {}", path, error),
|
||||
PlatformError::Write(path, error) => write!(f, "Write {}: {}", path, error),
|
||||
PlatformError::NotSupported => write!(f, "Not supported"),
|
||||
PlatformError::AttrNotFound(deets) => write!(f, "Attribute not found: {}", deets),
|
||||
PlatformError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets),
|
||||
PlatformError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error),
|
||||
PlatformError::Io(path, detail) => write!(f, "std::io error: {} {}", path, detail),
|
||||
PlatformError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
|
||||
PlatformError::NoAuraNode => write!(f, "No Aura keyboard node found"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PlatformError {}
|
||||
|
||||
impl From<rusb::Error> for PlatformError {
|
||||
fn from(err: rusb::Error) -> Self {
|
||||
PlatformError::USB(err)
|
||||
}
|
||||
}
|
||||
55
rog-platform/src/hid_raw.rs
Normal file
55
rog-platform/src/hid_raw.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use std::{fs::OpenOptions, io::Write, path::PathBuf};
|
||||
|
||||
use log::{info, warn};
|
||||
|
||||
use crate::error::{PlatformError, Result};
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
pub struct HidRaw(PathBuf);
|
||||
|
||||
impl HidRaw {
|
||||
pub fn new(id_product: &str) -> Result<Self> {
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("enumerator failed".into(), err)
|
||||
})?;
|
||||
|
||||
enumerator.match_subsystem("hidraw").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
for device in enumerator
|
||||
.scan_devices()
|
||||
.map_err(|e| PlatformError::Io("enumerator".to_owned(), e))?
|
||||
{
|
||||
if let Some(parent) = device
|
||||
.parent_with_subsystem_devtype("usb", "usb_device")
|
||||
.map_err(|e| PlatformError::Io(device.devpath().to_string_lossy().to_string(), e))?
|
||||
{
|
||||
if let Some(parent) = parent.attribute_value("idProduct") {
|
||||
if parent == id_product {
|
||||
if let Some(dev_node) = device.devnode() {
|
||||
info!("Using device at: {:?} for LED control", dev_node);
|
||||
return Ok(Self(dev_node.to_owned()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(PlatformError::MissingFunction(format!(
|
||||
"hidraw dev {} not found",
|
||||
id_product
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn write_bytes(&self, message: &[u8]) -> Result<()> {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open(&self.0)
|
||||
.map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e))?;
|
||||
// println!("write: {:02x?}", &message);
|
||||
file.write_all(message)
|
||||
.map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e))
|
||||
}
|
||||
}
|
||||
59
rog-platform/src/keyboard_led.rs
Normal file
59
rog-platform/src/keyboard_led.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use log::warn;
|
||||
|
||||
use crate::{
|
||||
attr_u8, attr_u8_array,
|
||||
error::{PlatformError, Result},
|
||||
to_device,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, PartialEq, PartialOrd)]
|
||||
pub struct KeyboardLed(PathBuf);
|
||||
|
||||
impl KeyboardLed {
|
||||
pub fn new() -> Result<Self> {
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("enumerator failed".into(), err)
|
||||
})?;
|
||||
|
||||
enumerator.match_subsystem("leds").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
enumerator
|
||||
.match_sysname("asus::kbd_backlight")
|
||||
.map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
for device in enumerator.scan_devices().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("scan_devices failed".into(), err)
|
||||
})? {
|
||||
return Ok(Self(device.syspath().to_owned()));
|
||||
}
|
||||
Err(PlatformError::MissingFunction(
|
||||
"asus::kbd_backlight not found".into(),
|
||||
))
|
||||
}
|
||||
|
||||
attr_u8!(has_brightness, get_brightness, set_brightness, "brightness");
|
||||
|
||||
attr_u8_array!(
|
||||
has_keyboard_rgb_mode,
|
||||
get_keyboard_rgb_mode,
|
||||
set_keyboard_rgb_mode,
|
||||
"kbd_rgb_mode"
|
||||
);
|
||||
|
||||
attr_u8_array!(
|
||||
has_keyboard_rgb_state,
|
||||
get_keyboard_rgb_state,
|
||||
set_keyboard_rgb_state,
|
||||
"kbd_rgb_state"
|
||||
);
|
||||
}
|
||||
191
rog-platform/src/lib.rs
Normal file
191
rog-platform/src/lib.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
pub mod error;
|
||||
pub mod hid_raw;
|
||||
pub mod keyboard_led;
|
||||
pub mod platform;
|
||||
pub mod usb_raw;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use error::{PlatformError, Result};
|
||||
use udev::Device;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! attr_bool {
|
||||
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
|
||||
pub fn $hasser(&self) -> bool {
|
||||
match to_device(&self.0) {
|
||||
Ok(p) => crate::has_attr(&p, $attr_name),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn $getter(&self) -> Result<bool> {
|
||||
crate::read_attr_bool(&to_device(&self.0)?, $attr_name)
|
||||
}
|
||||
|
||||
pub fn $setter(&self, value: bool) -> Result<()> {
|
||||
crate::write_attr_bool(&mut to_device(&self.0)?, $attr_name, value)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! attr_u8 {
|
||||
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
|
||||
pub fn $hasser(&self) -> bool {
|
||||
match to_device(&self.0) {
|
||||
Ok(p) => crate::has_attr(&p, $attr_name),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn $getter(&self) -> Result<u8> {
|
||||
crate::read_attr_u8(&to_device(&self.0)?, $attr_name)
|
||||
}
|
||||
|
||||
pub fn $setter(&self, value: u8) -> Result<()> {
|
||||
crate::write_attr_u8(&mut to_device(&self.0)?, $attr_name, value)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! attr_u8_array {
|
||||
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
|
||||
pub fn $hasser(&self) -> bool {
|
||||
match to_device(&self.0) {
|
||||
Ok(p) => crate::has_attr(&p, $attr_name),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn $getter(&self) -> Result<Vec<u8>> {
|
||||
crate::read_attr_u8_array(&to_device(&self.0)?, $attr_name)
|
||||
}
|
||||
|
||||
pub fn $setter(&self, values: &[u8]) -> Result<()> {
|
||||
crate::write_attr_u8_array(&mut to_device(&self.0)?, $attr_name, values)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) fn to_device(sys_path: &Path) -> Result<Device> {
|
||||
Device::from_syspath(sys_path)
|
||||
.map_err(|e| PlatformError::Udev("Couldn't transform syspath to device".to_string(), e))
|
||||
}
|
||||
|
||||
pub fn has_attr(device: &Device, attr_name: &str) -> bool {
|
||||
for attr in device.attributes() {
|
||||
if attr.name() == attr_name {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn read_attr_bool(device: &Device, attr_name: &str) -> Result<bool> {
|
||||
if let Some(value) = device.attribute_value(attr_name) {
|
||||
let tmp = value.to_string_lossy();
|
||||
if tmp.trim() == "0" {
|
||||
return Ok(false);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
Err(PlatformError::AttrNotFound(attr_name.to_string()))
|
||||
}
|
||||
|
||||
pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<()> {
|
||||
device
|
||||
.set_attribute_value(attr, &(value as u8).to_string())
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
}
|
||||
|
||||
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
||||
if let Some(value) = device.attribute_value(attr_name) {
|
||||
let tmp = value.to_string_lossy();
|
||||
return Ok(tmp.parse::<u8>().map_err(|_| PlatformError::ParseNum)?);
|
||||
}
|
||||
Err(PlatformError::AttrNotFound(attr_name.to_string()))
|
||||
}
|
||||
|
||||
pub fn write_attr_u8(device: &mut Device, attr: &str, value: u8) -> Result<()> {
|
||||
device
|
||||
.set_attribute_value(attr, &(value).to_string())
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
}
|
||||
|
||||
pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result<Vec<u8>> {
|
||||
if let Some(value) = device.attribute_value(attr_name) {
|
||||
let tmp = value.to_string_lossy();
|
||||
let tmp = tmp
|
||||
.split(' ')
|
||||
.map(|v| u8::from_str_radix(v, 10).unwrap_or(0))
|
||||
.collect();
|
||||
return Ok(tmp);
|
||||
}
|
||||
Err(PlatformError::AttrNotFound(attr_name.to_string()))
|
||||
}
|
||||
|
||||
pub fn write_attr_u8_array(device: &mut Device, attr: &str, values: &[u8]) -> Result<()> {
|
||||
let tmp: String = values.iter().map(|v| format!("{} ", v)).collect();
|
||||
let tmp = tmp.trim();
|
||||
device
|
||||
.set_attribute_value(attr, &tmp)
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn check() {
|
||||
let data = [1, 2, 3, 4, 5];
|
||||
|
||||
let tmp: String = data.iter().map(|v| format!("{} ", v)).collect();
|
||||
let tmp = tmp.trim();
|
||||
assert_eq!(tmp, "1 2 3 4 5");
|
||||
|
||||
let tmp: Vec<u8> = tmp
|
||||
.split(' ')
|
||||
.map(|v| u8::from_str_radix(v, 10).unwrap_or(0))
|
||||
.collect();
|
||||
assert_eq!(tmp, &[1, 2, 3, 4, 5]);
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn find_led_node(id_product: &str) -> Result<Device, PlatformError> {
|
||||
// let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
// warn!("{}", err);
|
||||
// PlatformError::Udev("enumerator failed".into(), err)
|
||||
// })?;
|
||||
// enumerator.match_subsystem("hidraw").map_err(|err| {
|
||||
// warn!("{}", err);
|
||||
// PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
// })?;
|
||||
|
||||
// for device in enumerator.scan_devices().map_err(|err| {
|
||||
// warn!("{}", err);
|
||||
// PlatformError::Udev("scan_devices failed".into(), err)
|
||||
// })? {
|
||||
// if let Some(parent) = device
|
||||
// .parent_with_subsystem_devtype("usb", "usb_device")
|
||||
// .map_err(|err| {
|
||||
// warn!("{}", err);
|
||||
// PlatformError::Udev("parent_with_subsystem_devtype failed".into(), err)
|
||||
// })?
|
||||
// {
|
||||
// if parent
|
||||
// .attribute_value("idProduct")
|
||||
// .ok_or_else(|| PlatformError::NotFound("LED idProduct".into()))?
|
||||
// == id_product
|
||||
// {
|
||||
// if let Some(dev_node) = device.devnode() {
|
||||
// info!("Using device at: {:?} for LED control", dev_node);
|
||||
// return Ok(device);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Err(PlatformError::MissingFunction(
|
||||
// "ASUS LED device node not found".into(),
|
||||
// ))
|
||||
// }
|
||||
69
rog-platform/src/platform.rs
Normal file
69
rog-platform/src/platform.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use log::warn;
|
||||
|
||||
use crate::{
|
||||
attr_bool,
|
||||
error::{PlatformError, Result},
|
||||
to_device,
|
||||
};
|
||||
|
||||
/// The "platform" device provides access to things like:
|
||||
/// - dgpu_disable
|
||||
/// - egpu_enable
|
||||
/// - panel_od
|
||||
/// - dgpu_only
|
||||
/// - keyboard_mode, set keyboard RGB mode and speed
|
||||
/// - keyboard_state, set keyboard power states
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
pub struct AsusPlatform(PathBuf);
|
||||
|
||||
impl AsusPlatform {
|
||||
pub fn new() -> Result<Self> {
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("enumerator failed".into(), err)
|
||||
})?;
|
||||
enumerator.match_subsystem("platform").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
enumerator.match_sysname("asus-nb-wmi").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
for device in enumerator.scan_devices().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("scan_devices failed".into(), err)
|
||||
})? {
|
||||
return Ok(Self(device.syspath().to_owned()));
|
||||
}
|
||||
Err(PlatformError::MissingFunction(
|
||||
"asus-nb-wmi not found".into(),
|
||||
))
|
||||
}
|
||||
|
||||
attr_bool!(
|
||||
has_dgpu_disable,
|
||||
get_dgpu_disable,
|
||||
set_dgpu_disable,
|
||||
"dgpu_disable"
|
||||
);
|
||||
|
||||
attr_bool!(
|
||||
has_egpu_enable,
|
||||
get_egpu_enable,
|
||||
set_egpu_enable,
|
||||
"egpu_enable"
|
||||
);
|
||||
|
||||
attr_bool!(has_panel_od, get_panel_od, set_panel_od, "panel_od");
|
||||
|
||||
attr_bool!(
|
||||
has_gpu_mux_mode,
|
||||
get_gpu_mux_mode,
|
||||
set_gpu_mux_mode,
|
||||
"gpu_mux_mode"
|
||||
);
|
||||
}
|
||||
48
rog-platform/src/usb_raw.rs
Normal file
48
rog-platform/src/usb_raw.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use rusb::{Device, DeviceHandle};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::error::{PlatformError, Result};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct USBRaw(DeviceHandle<rusb::GlobalContext>);
|
||||
|
||||
impl USBRaw {
|
||||
pub fn new(id_product: u16) -> Result<Self> {
|
||||
for device in rusb::devices()?.iter() {
|
||||
let device_desc = device.device_descriptor()?;
|
||||
if device_desc.vendor_id() == 0x0b05 && device_desc.product_id() == id_product {
|
||||
let handle = Self::get_dev_handle(device)?;
|
||||
return Ok(Self(handle));
|
||||
}
|
||||
}
|
||||
|
||||
Err(PlatformError::MissingFunction(format!(
|
||||
"USBRaw dev {} not found",
|
||||
id_product
|
||||
)))
|
||||
}
|
||||
|
||||
fn get_dev_handle(
|
||||
device: Device<rusb::GlobalContext>,
|
||||
) -> Result<DeviceHandle<rusb::GlobalContext>> {
|
||||
// We don't expect this ID to ever change
|
||||
let mut device = device.open()?;
|
||||
device.reset()?;
|
||||
device.set_auto_detach_kernel_driver(true)?;
|
||||
device.claim_interface(0)?;
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
pub fn write_bytes(&self, message: &[u8]) -> Result<usize> {
|
||||
self.0
|
||||
.write_control(
|
||||
0x21, // request_type
|
||||
0x09, // request
|
||||
0x35e, // value
|
||||
0x00, // index
|
||||
message,
|
||||
Duration::from_millis(200),
|
||||
)
|
||||
.map_err(|e| PlatformError::USB(e))
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ pub struct LedSupportedFunctions {
|
||||
#[derive(Serialize, Deserialize, Type, Debug, Default)]
|
||||
pub struct RogBiosSupportedFunctions {
|
||||
pub post_sound: bool,
|
||||
pub dedicated_gfx: bool,
|
||||
pub dgpu_only: bool,
|
||||
pub panel_overdrive: bool,
|
||||
pub dgpu_disable: bool,
|
||||
pub egpu_enable: bool,
|
||||
@@ -95,7 +95,7 @@ impl fmt::Display for RogBiosSupportedFunctions {
|
||||
writeln!(f, "\tPanel Overdrive: {}", self.panel_overdrive)?;
|
||||
writeln!(f, "\tdGPU disable switch: {}", self.dgpu_disable)?;
|
||||
writeln!(f, "\teGPU enable switch: {}", self.egpu_enable)?;
|
||||
writeln!(f, "\tDedicated GFX switch: {}", self.dedicated_gfx)?;
|
||||
writeln!(f, "\tDedicated GFX switch: {}", self.dgpu_only)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user