Compare commits

...

125 Commits
4.6.1 ... 4.7.2

Author SHA1 Message Date
Luke D. Jones
6c375a9951 Prep new release 2023-09-08 13:22:15 +12:00
Luke D. Jones
4641e19c43 Fix bad keybaord layout 2023-09-04 10:19:57 +12:00
Luke D. Jones
91f0c2ea14 Fix loading of fan curves
Closes #402

Signed-off-by: Luke D. Jones <luke@ljones.dev>
2023-09-04 10:18:48 +12:00
Luke Jones
b4a8cb9de2 Merge branch 'srivatsarog-main-patch-78688' into 'main'
Update aura_support.ron

See merge request asus-linux/asusctl!169
2023-09-03 08:45:39 +00:00
Luke Jones
67bbcdb964 Merge branch 'main' into 'srivatsarog-main-patch-78688'
# Conflicts:
#   rog-aura/data/aura_support.ron
2023-09-03 08:37:52 +00:00
Luke Jones
8acfe0a9e8 Merge branch 'main' into 'main'
aura: Support for G733PZ

See merge request asus-linux/asusctl!167
2023-09-03 08:36:20 +00:00
Luke D. Jones
5f6e6ec382 gex: rename gnome-44, add gnome-45 2023-08-31 14:36:01 +12:00
Luke D. Jones
cf92526d87 Set cargo resolver 2023-08-31 12:42:31 +12:00
Luke D. Jones
f290594562 Prep release 2023-08-26 21:40:45 +12:00
Luke D. Jones
423bd54f79 Fixes: bugfixes in aura config loading 2023-08-26 21:35:38 +12:00
Luke Jones
ea0eaef8a6 Update README.md 2023-08-24 10:22:26 +00:00
Luke Jones
ef62a26148 Merge branch 'main' into 'main'
add aura support for GU603VV

See merge request asus-linux/asusctl!170
2023-08-20 06:13:20 +00:00
Yifan Zhu
2f916fa4e5 add aura support for GU603VV 2023-08-20 06:13:20 +00:00
Luke D. Jones
e42fd10404 Update deps 2023-08-14 13:20:40 +12:00
Luke D. Jones
93edd1b632 Add gv601v singlezone advanced 2023-08-13 18:22:21 +12:00
Luke D. Jones
6957a08d83 Fix: Corrections in anime detection
Closes #387
2023-08-11 09:48:22 +12:00
Luke D. Jones
98569b98e7 Remove a dbg!() x2 2023-08-10 09:50:01 +12:00
Luke D. Jones
573568d6e2 Remove a dbg!() 2023-08-10 09:49:13 +12:00
Luke D. Jones
3ec37a4dac Fix: For anime look for usbraw device before hidraw device
Closes #387
2023-08-02 14:14:08 +12:00
Luke D. Jones
11483b28a6 Fix: Further refine the CLI for fan curve control
Should close #385
2023-08-01 19:30:33 +12:00
Luke D. Jones
2cce83d164 Fix: asusd should reload defualt fan-curves if the config file fails
Closes #385
2023-08-01 09:30:54 +12:00
Luke D. Jones
42b92f3b87 Fix: reimplement fetching of fan curves on CLI
Partial close of #385
2023-08-01 09:18:27 +12:00
gabi
b652fd15a2 Update aura_support.ron 2023-07-28 06:16:39 +00:00
Luke D. Jones
9154aaa97c Add distro packaging dir + spec file for fedora 2023-07-27 10:13:10 +12:00
Interfector18
9e65921c0a aura: Support for G733PZ 2023-07-24 17:44:59 +02:00
Luke D. Jones
8d8b5e5f51 aura: support GV601V LED modes 2023-07-24 14:07:01 +12:00
Luke D. Jones
9418b63454 Bump new release 2023-07-24 10:23:05 +12:00
Luke D. Jones
2d396a49da Update crate versions 2023-07-24 10:14:24 +12:00
Luke D. Jones
a6d89a622b Various cleanup. Add GA402X LED modes 2023-07-24 10:04:10 +12:00
Luke D. Jones
51bcb0082b profiles: add mid fan curve support 2023-07-24 09:29:56 +12:00
Luke D. Jones
eb54250e4d aura: support FX505G 2023-07-24 09:28:09 +12:00
Luke D. Jones
eafc831231 gex: update xml and aura power parsing 2023-07-12 14:21:57 +12:00
Luke D. Jones
c625e97b7b Update changelog 2023-07-11 21:08:10 +12:00
Luke D. Jones
fea56879d6 Update changelog 2023-07-11 21:06:27 +12:00
Luke D. Jones
03052e129b aura: update dbus xml 2023-07-11 21:02:40 +12:00
Luke D. Jones
3dbc893905 aura: update bindings 2023-07-11 21:00:42 +12:00
Luke D. Jones
50152961c7 aura: refactor modern rog power settings 2023-07-11 20:59:43 +12:00
Luke D. Jones
8be0e7e6bf gex: update laptop feature toggle to switch primary 2023-07-06 22:00:59 +12:00
Luke D. Jones
d6d4a00fc3 gex: add keyboard LED mode setting 2023-07-04 21:22:30 +12:00
Luke D. Jones
611140716c gex: map more of dbus methods and notifs 2023-07-04 20:08:42 +12:00
Luke D. Jones
a09f7b5275 gex: parse led power from dbus 2023-07-04 18:49:52 +12:00
Luke D. Jones
823958492e rename keyboard led power dbus methods 2023-07-04 10:17:11 +12:00
Luke D. Jones
668135eab3 Update readme 2023-07-03 23:06:19 +12:00
Luke D. Jones
622e07505d gex: begin adding aura control dbus 2023-07-03 23:04:06 +12:00
Luke D. Jones
5c159d2294 Set toolchain to stable 2023-07-03 20:14:14 +12:00
Luke D. Jones
6cfa09a02b Update readme 2023-07-03 16:20:46 +12:00
Luke D. Jones
95666cc40b Update deps 2023-07-03 16:07:38 +12:00
Luke D. Jones
458d58c87c Update changelog 2023-07-03 16:05:46 +12:00
Luke D. Jones
7328ebdda3 gex: cleanup and rename 2023-07-03 15:51:26 +12:00
Luke D. Jones
14d043bbc3 RCC: add tray enable/disable, move app settings to page 2023-07-03 15:02:25 +12:00
Luke D. Jones
98dec6403c gex: adjust tsconfig 2023-07-02 21:58:50 +12:00
Luke D. Jones
3546f5bd21 gex: add toggle for anime powersave anim 2023-07-02 21:09:17 +12:00
Luke D. Jones
db1683de46 gex: temporary checking of which primary quicktoggle to use 2023-07-02 19:15:55 +12:00
Luke D. Jones
669c8ac3c7 gex: make quickmenu a module 2023-07-02 17:30:20 +12:00
Luke D. Jones
4f3a6ce1c6 gex: trial of using qucik submenu toggles 2023-07-02 11:37:36 +12:00
Luke Jones
6d3918ccf0 clean up bindings 2023-07-01 12:00:46 +00:00
Luke D. Jones
b002187b39 gex: trial of updating quicktoggle with dbus signal 2023-07-01 23:14:54 +12:00
Luke D. Jones
13965b2261 gex: add eslint, cleanup parsing of some stuff 2023-07-01 21:47:31 +12:00
Luke D. Jones
b182fbd323 gex: add anime power quicktoggle 2023-07-01 20:09:28 +12:00
Luke D. Jones
19b28f202c gex: Add slider for charge control 2023-07-01 19:17:02 +12:00
Luke D. Jones
ed51a7fa14 gex: fix and update 2023-07-01 18:03:05 +12:00
Luke D. Jones
c94358a8f3 gex: itemize the quicks and indicators 2023-07-01 17:18:11 +12:00
Luke D. Jones
2a8ca0a39a asusd: cleanup platform notifs, prevent more duplications 2023-07-01 12:31:40 +12:00
Luke D. Jones
83455a5ba3 Update deps 2023-06-30 15:57:18 +12:00
Luke D. Jones
bc776deb70 gex: more cleanup 2023-06-30 11:30:09 +12:00
Luke D. Jones
59b1059aee gex: cleanup 2023-06-30 10:43:19 +12:00
Luke D. Jones
dbe80d1914 gex: simplify build 2023-06-29 23:05:00 +12:00
Luke D. Jones
e325ebed18 gex: working quicktoggle example 2023-06-29 20:48:15 +12:00
Luke D. Jones
a743bda6e0 gex: cleanup 2023-06-29 17:42:57 +12:00
Luke D. Jones
15e6782e10 gex: map anime dbus data 2023-06-29 15:16:21 +12:00
Luke D. Jones
6b058c9922 gex: trial of dbus mthods 2023-06-29 12:58:11 +12:00
Luke D. Jones
fc8879ac24 gex: dbus class template 2023-06-28 22:50:56 +12:00
Luke D. Jones
4d2d5707a1 Begin reimplement gex to use generated bindings and dbus xml 2023-06-28 21:54:17 +12:00
Luke D. Jones
439c830311 Cleanup rog-aura usb tests 2023-06-28 10:07:11 +12:00
Luke D. Jones
91223d4ced Regenerate dbus xml 2023-06-27 22:19:29 +12:00
Luke D. Jones
7b17a13ce7 ridiculous refactor to allow enums to be dbus strings for better TS generation 2023-06-27 21:16:13 +12:00
Luke D. Jones
fca7d23a31 Update pipeline 2023-06-26 13:54:07 +12:00
Luke D. Jones
0122138b3b Add index.html 2023-06-26 13:43:06 +12:00
Luke D. Jones
7b495e7587 rcc: instant apply keyboard settings 2023-06-26 12:28:48 +12:00
Luke D. Jones
970cf9ae59 Support for G634J LED modes (layout is in progress) 2023-06-26 12:01:21 +12:00
Luke D. Jones
ad990c6ae1 Move G513I* to G513I in arua DB to catch full series of this range
Closes #336
2023-06-26 11:52:14 +12:00
Luke D. Jones
cd8cc013a4 Aura: set the LED brightness if settign a mode
Closes #355
2023-06-26 11:33:05 +12:00
Luke D. Jones
acf41c1783 Add support for mini_led_mode get/set
- asusd get/set, zbus methods
- Rog control center notification, tray menu, UI entry
2023-06-26 10:44:58 +12:00
Luke D. Jones
03c9f06569 asusctl: remove the panics from CLI
closes #364
2023-06-26 09:41:42 +12:00
Luke D. Jones
036a5018e0 Removed a duplication of charge limit notification 2023-06-25 21:15:27 +12:00
Luke D. Jones
81529b7374 Update GL503 led config 2023-06-25 20:59:26 +12:00
Luke D. Jones
2289af3ef6 Update discord link.
Closes #363
2023-06-25 20:51:17 +12:00
Luke D. Jones
633ffdf962 Support for GV601VI LED modes
Closes #370
2023-06-25 20:49:28 +12:00
Luke D. Jones
cb88c9f0e2 Fix: prevent multiple notifications from profile change 2023-06-25 20:43:43 +12:00
Luke D. Jones
8b77078a6f Animatrix: simulators, add features 2023-06-25 18:29:19 +12:00
Luke D. Jones
3d6d92ae7d Animatrix: gu604 sim 2023-06-25 16:36:19 +12:00
Luke D. Jones
55723b7b77 animatrix mapping: gu604 2023-06-25 11:39:56 +12:00
Luke D. Jones
7796ba0603 Animatrix sim: fixxess 2023-06-24 22:02:21 +12:00
Luke D. Jones
d3aababef5 animatrix simulator for ga402 2023-06-24 19:00:25 +12:00
Luke D. Jones
4611c08085 Add the missing dirs, dumbarse 2023-06-24 13:15:11 +12:00
Luke D. Jones
0a008a653a Animatrix: Default to GA402 style if Unknown, use default-workspace.
Also rename daemon crates to the bin names they use to be less confusing.

Signed-off-by: Luke D. Jones <luke@ljones.dev>
2023-06-24 12:57:03 +12:00
Luke D. Jones
cd5daa17d0 Anime: Enabled setting builtin animations 2023-06-21 13:34:08 +12:00
Luke D. Jones
a0529e0efd Better organise anime tests 2023-06-21 10:09:06 +12:00
Luke D. Jones
3e0aeea6c6 Add inotify::WatchMask::MODIFY to inotify watch mask.
Closes #362
2023-06-20 22:23:54 +12:00
Luke D. Jones
e2fb1d44b5 Anime: Diagonal asus gifs done 2023-06-20 21:58:27 +12:00
Luke D. Jones
04543eeca0 Aura: add support for Rear Glow power modes 2023-06-18 19:48:08 +12:00
Luke D. Jones
68ee62fef1 Anime: add base brightness control (dbus, cli) 2023-06-16 11:50:38 +12:00
Luke D. Jones
e523e4e9a2 Anime: GU604 images correct 2023-06-16 10:43:15 +12:00
Luke D. Jones
ea2d80cc44 Anime: incorrect dimensions and pitch 2023-06-16 00:34:45 +12:00
Luke D. Jones
40e00c4739 Anime: fixups, GU604 support 2023-06-15 23:53:24 +12:00
Luke D. Jones
cdc42193d1 Update deps 2023-06-14 20:30:42 +12:00
Luke D. Jones
3a18506510 Add "Unknown" to (not really) supported AniMe list
Intention is to allow users to at least control the power state of the
device (turn off) if the phyciscal display isn't yet supported.

Partial address of #354
2023-06-14 20:25:27 +12:00
Luke D. Jones
fa671e53d8 Add sdl32 to gitlab pipeline 2023-06-14 20:25:27 +12:00
Luke D. Jones
002dc8516d Half-arsed visuals for virtual anime 2023-06-14 20:25:27 +12:00
Luke D. Jones
2a38f69cc4 Begin implementing virtual devices for testing and stuff 2023-06-14 20:25:27 +12:00
Luke Jones
a14a37d0da Merge branch 'optional-stripping' into 'main'
Optional symbol stripping in Makefile

See merge request asus-linux/asusctl!165
2023-06-13 23:17:22 +00:00
Greg Land
b105ff5180 Optional symbol stripping in Makefile
Packaging systems have options to handle symbol stripping.  This lets
the users of the software enable or disable symbol stripping based on
their own preference or need.
2023-06-13 19:01:08 -04:00
Luke Jones
d202fcd97a Merge branch 'fix-install-program-target' into 'main'
Fixed issue preventing debug builds using Makefile

See merge request asus-linux/asusctl!163
2023-06-13 21:41:56 +00:00
Greg Land
15732ecd82 Fixed issue preventing debug builds using Makefile
install-program was always assuming that release was the only target
directory that could exist.  This would cause install-program to fail
with DEBUG=1 passed to the makefile.

DEBUG flag now correctly sets a TARGET and sets the build profile to dev
for debug builds.
2023-06-13 13:30:23 -04:00
Luke Jones
8508110ba0 Merge branch 'fix-g513qy' into 'main'
Fix broken Aura on G513QY

See merge request asus-linux/asusctl!162
2023-06-07 07:09:00 +00:00
CryoByte33
cafb64d57b Fix broken Aura on G513QY 2023-06-07 04:36:38 +02:00
Luke D. Jones
7515eafc45 Rmeove notification handle tracking limit
Fixes issue with KDE profile change notif disappearing.

closes #353
2023-05-20 19:07:40 +12:00
Luke D. Jones
b6c6f10bdf Fix test 2023-05-20 19:05:22 +12:00
Luke D. Jones
35352a8a7c Support for GL503V LED modes 2023-05-20 19:04:18 +12:00
Luke Jones
0c3bebdeb9 Merge branch 'main' into 'main'
Add led modes for GV601VI

See merge request asus-linux/asusctl!161
2023-05-16 22:57:50 +00:00
Mateo Juric
1394c12967 Add led modes for GV601VI 2023-05-17 00:04:36 +02:00
Luke D. Jones
cbc1f6f5bb Modify two TUF aura DB entries to match full range 2023-04-27 19:46:17 +12:00
Luke D. Jones
7ae0f896cf Update deps 2023-04-27 16:08:52 +12:00
Luke D. Jones
fb0374512d Fix rog-control-center not reopening if is set 2023-04-27 16:01:07 +12:00
Luke D. Jones
14f031ad34 Better update of aura modes if supported list changed 2023-04-27 10:57:45 +12:00
201 changed files with 17989 additions and 2903 deletions

11
.gitignore vendored
View File

@@ -8,4 +8,13 @@ vendor_*
.vscode-ctags
.vscode
.~lock.*
*.ods#
*.ods#
# gnome extension
node-modules
bindings/ts/*.d.ts
bindings/ts/*.js.map
desktop-extensions/gnome*/dist
desktop-extensions/gnome*/node_modules
desktop-extensions/gnome*/schemas/gschemas.compiled
desktop-extensions/gnome*/*.zip

View File

@@ -17,7 +17,7 @@ image: rust:latest
- target/release/.cargo-lock
before_script:
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev libsdl2-dev libsdl2-gfx-dev
stages:
- format
@@ -52,7 +52,7 @@ test:
<<: *rust_cache
script:
- mkdir -p .git/hooks > /dev/null
- cargo test
- cargo test --all
release:
only:
@@ -62,7 +62,7 @@ release:
- make && make vendor
artifacts:
paths:
- vendor_asusctl_*.tar.xz
- vendor_asusctl*.tar.xz
- cargo-config
pages:
@@ -75,10 +75,10 @@ pages:
- rm -rf public
- mkdir public
- cp -R target/doc/* public
- cp misc/index.html public
- cp extra/index.html public
artifacts:
paths:
- public
variables:
GIT_SUBMODULE_STRATEGY: normal

View File

@@ -5,6 +5,71 @@ 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]
## [v4.7.2]
### Added
- Support for G733PZ LED modes
- Support for G713RC LED modes
### Changed
- Fix loading of fan curves from stored settings
## [v4.7.1]
### Changed
- Fixes to asusctl CLI tool to show fan curves
- Fixes to asusd to ensure fan curve defaults are loaded if the config file fails
- Further refine the asusctl CLI for fan-curve control
- Fixes to AniMe detection
- Fixes to aura config creation/loading
### Added
- Support for GV601V LED modes
## [v4.7.0]
### Added
- Support for FX507Z LED modes
- Support for GL503V LED modes
- Support for G733C LED modes
- Support for GV601VI LED modes
- Support for FX505G LED modes
- Support for GA402X LED modes
- Support for G634J LED modes (layout is in progress)
- Support the Rear Glow on some laptops
- Added field to aura_support to determine which LED power zones are supported. This will need folks to contribute data.
- Support M16 matrix display
- Custom images
- Pixel gifs
- Power options
- Builtin animations
- In-progress simulators for GA402, GU604 animatrix, optional build and takes a single arg
- Add `model_override` option to anime config, this is handy for forcing a model for "Unknown" anime, and for simulators
- Add `mini_led_mode` support to asusd and zbus crates (requires kernel patch https://lkml.org/lkml/2023/6/19/1264)
- Add `mini_led_mode` toggle to rog-control-center GUI, tray, notifications
- Add generation of typescript types from the rust types used via dbus using typeshare
- Add generation of introspection XML from asusd dbus
- Add a reworked gnome extension to the main repo under `desktop-extensions/gnome/`. This was done to better keep the extension in sync with work done on asusd, especially around breaking dbus
- Add support for the mid fan custom curves on some laptops
### Changed
- Move FX506HC to FX506H in arua DB to catch full series of this range
- Move FX506LH to FX506L in arua DB to catch full series of this range
- Move G513I* to G513I in arua DB to catch full series of this range
- Remove notification handle tracking limit, fixes KDE issue with profile notif
- Rename daemon and daemon-user crates to asusd and asusd-user to not be confusing in workspace naming
- Prevent the multiple notifications from a profile change from occuring (too many functions with side effects!)
- Apply keyboard brightness when setting a mode
- Update GL503 led config
- Arua LED power control has been heavily refactored for 0x19b6+ devices
- Rog Control Center:
- Added option to enable/disable system tray
- Added button to fully quit app (exits from background)
- Moved application settings to new page
- Aura LED power refactor is now taken advantage of in RCC, exposing all settings
### BREAKING
- All Anime related DBUS methods/notifs are changed
- All dbus interfaces that handled an enum have now been forced to use the enum as String type, not uint or similar, this unfortunately breaks a heap of stuff but has the benefit of allowing asusctl to use crates to generate a typescript (or other) binding to the types being used by zbus for the proxies. The implication here is that there will be an eventual tighter integration with the gnome extension and maybe KDE also.
## [v4.6.2]
- Fix rog-control-center not reopening if `startup_in_background` is set
## [v4.6.1]
### Added
- Support for G733Z LED modes
@@ -630,4 +695,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix small deadlock with awaits
## [1.0.0]
## [1.0.0]

1136
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,10 @@
[workspace]
members = ["asusctl", "config-traits", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
members = ["asusctl", "asusd", "asusd-user", "config-traits", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
default-members = ["asusctl", "asusd", "asusd-user", "rog-control-center"]
resolver = "2"
[workspace.package]
version = "4.6.1"
version = "4.7.2"
[workspace.dependencies]
async-trait = "^0.1"
@@ -11,14 +13,15 @@ concat-idents = "^1.1"
dirs = "^4.0"
smol = "^1.3"
zbus = "^3.6"
logind-zbus = { version = "^3.1.0" } #, default-features = false, features = ["non_blocking"] }
zbus = "~3.14.1"
logind-zbus = { version = "~3.1" } #, default-features = false, features = ["non_blocking"] }
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
toml = "^0.5.10"
ron = "*"
typeshare = "1.0.0"
log = "^0.4"
env_logger = "^0.10.0"
@@ -46,6 +49,7 @@ lto = "fat"
debug = false
opt-level = 3
panic = "abort"
#codegen-units = 1
[profile.dev]
debug = true

View File

@@ -19,10 +19,15 @@ LEDCFG := aura_support.ron
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
STRIP_BINARIES ?= 0
DEBUG ?= 0
ifeq ($(DEBUG),0)
ARGS += --release
TARGET = release
else
ARGS += --profile dev
TARGET = debug
endif
VENDORED ?= 0
@@ -39,11 +44,11 @@ distclean:
rm -rf .cargo vendor vendor.tar.xz
install-program:
$(INSTALL_PROGRAM) "./target/release/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
$(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
$(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
install-data:
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
@@ -110,15 +115,35 @@ vendor:
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
rm -rf vendor
bindings:
typeshare ./rog-anime/src/ --lang=typescript --output-file=bindings/ts/anime.ts
typeshare ./rog-aura/src/ --lang=typescript --output-file=bindings/ts/aura.ts
typeshare ./rog-profiles/src/ --lang=typescript --output-file=bindings/ts/profiles.ts
typeshare ./rog-platform/src/ --lang=typescript --output-file=bindings/ts/platform.ts
introspect:
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Aura -x > bindings/dbus-xml/org-asuslinux-aura-4.xml
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Anime -x > bindings/dbus-xml/org-asuslinux-anime-4.xml
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Platform -x > bindings/dbus-xml/org-asuslinux-platform-4.xml
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Power -x > bindings/dbus-xml/org-asuslinux-power-4.xml
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Profile -x > bindings/dbus-xml/org-asuslinux-profile-4.xml
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Supported -x > bindings/dbus-xml/org-asuslinux-supported-4.xml
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Introspectable"]' bindings/dbus-xml/org-asuslinux-*
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Properties"]' bindings/dbus-xml/org-asuslinux-*
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Peer"]' bindings/dbus-xml/org-asuslinux-*
build:
ifeq ($(VENDORED),1)
@echo "version = $(VERSION)"
tar pxf vendor_asusctl_$(VERSION).tar.xz
endif
cargo build $(ARGS)
strip -s ./target/release/$(BIN_C)
strip -s ./target/release/$(BIN_D)
strip -s ./target/release/$(BIN_U)
strip -s ./target/release/$(BIN_ROG)
ifneq ($(STRIP_BINARIES),0)
strip -s ./target/$(TARGET)/$(BIN_C)
strip -s ./target/$(TARGET)/$(BIN_D)
strip -s ./target/$(TARGET)/$(BIN_U)
strip -s ./target/$(TARGET)/$(BIN_ROG)
endif
.PHONY: all clean distclean install uninstall update build
.PHONY: all clean distclean install uninstall update build bindings

View File

@@ -1,6 +1,6 @@
# `asusctl` for ASUS ROG
[![](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/donate/?hosted_button_id=4V2DEPS7K6APC) - [Asus Linux Website](https://asus-linux.org/)
[Become a Patron!](https://www.patreon.com/bePatron?u=7602281) - [Asus Linux Website](https://asus-linux.org/)
**WARNING:** Many features are developed in tandem with kernel patches. If you see a feature is missing you either need a patched kernel, or v6.1 which has all my work merged upstream.
@@ -31,7 +31,7 @@ a system-level daemon should.
## Discord
[Discord server link](https://discord.gg/4ZKGd7Un5t)
[Discord server link](https://discord.gg/WTHnqabm)
## SUPPORTED LAPTOPS
@@ -48,13 +48,11 @@ and AniMe parts should work regardless of your latop make.
## Implemented
- [X] System daemon
- [X] GUI app
- [X] User notifications daemon
- [X] GUI app (includes tray and notifications)
- [X] Setting/modifying built-in LED modes
- [X] Per-key LED setting
- [X] Fancy LED modes (See examples) (currently being reworked)
- [X] Saving settings for reload
- [X] AniMatrix display on G14 models that include it
- [X] AniMatrix display on G14 and M16 models that include it
- [X] Set battery charge limit (with kernel supporting this)
- [X] Fan curve control on supported laptops (G14/G15, some TUF like FA507)
- [X] Toggle bios setting for boot/POST sound
@@ -81,13 +79,13 @@ Requirements are rust >= 1.57 installed from rustup.io if the distro provided ve
sudo make install
**popos (unsuported):**
sudo apt install cmake libclang-dev libudev-dev libgtk-3-dev libclang-dev libglib2.0-dev libatkmm-1.6-dev libpangomm-1.4-dev librust-gdk-pixbuf-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
make
sudo make install
**fedora:**
@@ -130,8 +128,16 @@ Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
Generation of the bindings with `make bindings` requires `typeshare` to be installed.
Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`.
# OTHER
## AniMe Matrix simulator
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop *with* the display, the simulated display will be used instead of the physical display.
## Supporting more laptops
Please file a support request.

View File

@@ -11,7 +11,7 @@ rog_aura = { path = "../rog-aura" }
rog_dbus = { path = "../rog-dbus" }
rog_profiles = { path = "../rog-profiles" }
rog_platform = { path = "../rog-platform" }
daemon = { path = "../daemon" }
asusd = { path = "../asusd" }
gumdrop.workspace = true
toml.workspace = true

View File

@@ -32,7 +32,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let zone = Effect::DoomFlicker(rog_aura::effects::DoomFlicker::new(
LedCode::SingleZone,
Colour(200, 110, 0),
Colour {
r: 200,
g: 110,
b: 0,
},
100,
10,
));

View File

@@ -1,21 +1,24 @@
use gumdrop::Options;
use rog_anime::usb::{AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness};
use rog_anime::AnimeType;
#[derive(Options)]
pub struct AnimeCommand {
#[options(help = "print help message")]
pub help: bool,
#[options(meta = "", help = "override the display type")]
pub override_type: Option<AnimeType>,
#[options(meta = "", help = "enable/disable the display")]
pub enable_display: Option<bool>,
#[options(meta = "", help = "enable/disable the builtin run/powersave animation")]
pub enable_powersave_anim: Option<bool>,
#[options(
meta = "",
help = "enable/disable the panel LEDs (does not erase last image)"
help = "set global base brightness value <Off, Low, Med, High>"
)]
pub enable: Option<bool>,
#[options(
meta = "",
help = "enable/disable system animations (boot/sleep/shutdown)"
)]
pub boot_enable: Option<bool>,
#[options(meta = "", help = "set global AniMe brightness value")]
pub brightness: Option<f32>,
pub brightness: Option<Brightness>,
#[options(meta = "", help = "set global (image) brightness value")]
pub image_brightness: Option<f32>,
#[options(help = "clear the display")]
pub clear: bool,
#[options(command)]
@@ -32,6 +35,36 @@ pub enum AnimeActions {
Gif(AnimeGif),
#[options(help = "display an animated diagonal/pixel-perfect GIF")]
PixelGif(AnimeGifDiagonal),
#[options(help = "change which builtin animations are shown")]
SetBuiltins(Builtins),
}
#[derive(Options)]
pub struct Builtins {
#[options(help = "print help message")]
pub help: bool,
#[options(
meta = "",
help = "Default is used if unspecified, <default:GlitchConstruction, StaticEmergence>"
)]
pub boot: AnimBooting,
#[options(
meta = "",
help = "Default is used if unspecified, <default:BinaryBannerScroll, RogLogoGlitch>"
)]
pub awake: AnimAwake,
#[options(
meta = "",
help = "Default is used if unspecified, <default:BannerSwipe, Starfield>"
)]
pub sleep: AnimSleeping,
#[options(
meta = "",
help = "Default is used if unspecified, <default:GlitchOut, SeeYa>"
)]
pub shutdown: AnimShutdown,
#[options(meta = "", help = "set/apply the animations <true/false>")]
pub set: Option<bool>,
}
#[derive(Options)]

View File

@@ -4,7 +4,7 @@ use gumdrop::Options;
use rog_aura::error::Error;
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed};
#[derive(Options)]
#[derive(Options, Debug)]
pub struct LedPowerCommand1 {
#[options(help = "print help message")]
pub help: bool,
@@ -20,55 +20,43 @@ pub struct LedPowerCommand1 {
pub sleep: Option<bool>,
}
#[derive(Options)]
#[derive(Options, Debug)]
pub struct LedPowerCommand2 {
#[options(help = "print help message")]
pub help: bool,
#[options(command)]
pub command: Option<SetAuraEnabled>,
pub command: Option<SetAuraZoneEnabled>,
}
#[derive(Options)]
pub enum SetAuraEnabled {
#[derive(Options, Debug)]
pub enum SetAuraZoneEnabled {
/// Applies to both old and new models
#[options(help = "set <keyboard, logo, lightbar> to enabled while device is awake")]
Awake(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to enabled while the device is booting")]
Boot(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to animate while the device is suspended")]
Sleep(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to animate while the device is shutdown")]
Shutdown(AuraEnabled),
#[options(help = "")]
Keyboard(AuraPowerStates),
#[options(help = "")]
Logo(AuraPowerStates),
#[options(help = "")]
Lightbar(AuraPowerStates),
#[options(help = "")]
Lid(AuraPowerStates),
#[options(help = "")]
RearGlow(AuraPowerStates),
}
#[derive(Debug, Clone, Default, Options)]
pub struct AuraEnabled {
#[derive(Debug, Clone, Options)]
pub struct AuraPowerStates {
#[options(help = "print help message")]
pub help: bool,
#[options(meta = "", help = "<true/false>")]
pub keyboard: Option<bool>,
#[options(meta = "", help = "<true/false>")]
pub logo: Option<bool>,
#[options(meta = "", help = "<true/false>")]
pub lightbar: Option<bool>,
#[options(meta = "", help = "<true/false>")]
pub lid: Option<bool>,
#[options(help = "defaults to false if option unused")]
pub boot: bool,
#[options(help = "defaults to false if option unused")]
pub awake: bool,
#[options(help = "defaults to false if option unused")]
pub sleep: bool,
#[options(help = "defaults to false if option unused")]
pub shutdown: bool,
}
// impl FromStr for AuraEnabled {
// type Err = Error;
// fn from_str(s: &str) -> Result<Self, Self::Err> {
// let s = s.to_lowercase();
// Ok(Self {
// help: false,
// keyboard: None,
// logo: None,
// lightbar: None,
// })
// }
// }
#[derive(Options)]
pub struct LedBrightness {
level: Option<u32>,

View File

@@ -9,15 +9,16 @@ use aura_cli::{LedPowerCommand1, LedPowerCommand2};
use gumdrop::{Opt, Options};
use profiles_cli::{FanCurveCommand, ProfileCommand};
use rog_anime::usb::get_anime_type;
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
use rog_aura::power::KbAuraPowerState;
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
use rog_aura::{self, AuraEffect};
use rog_dbus::RogDbusClientBlocking;
use rog_platform::platform::GpuMode;
use rog_platform::supported::*;
use rog_profiles::error::ProfileError;
use crate::aura_cli::LedBrightness;
use crate::aura_cli::{AuraPowerStates, LedBrightness};
use crate::cli_opts::*;
mod anime_cli;
@@ -36,69 +37,52 @@ fn main() {
..Default::default()
},
Err(err) => {
panic!("source {}", err);
println!("Error: {}", err);
return;
}
};
let (dbus, _) = RogDbusClientBlocking::new()
.map_err(|e| {
print_error_help(&e, None);
panic!("Could not start dbus client");
})
.unwrap();
if let Ok((dbus, _)) = RogDbusClientBlocking::new().map_err(|e| {
print_error_help(&e, None);
}) {
if let Ok(supported) = dbus
.proxies()
.supported()
.supported_functions()
.map_err(|e| {
print_error_help(&e, None);
})
{
if parsed.version {
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
println!();
print_info();
}
let supported = dbus
.proxies()
.supported()
.supported_functions()
.map_err(|e| {
print_error_help(&e, None);
panic!("Could not start dbus proxy");
})
.unwrap();
if parsed.version {
print_versions();
println!();
print_laptop_info();
}
if let Err(err) = do_parsed(&parsed, &supported, &dbus) {
print_error_help(&*err, Some(&supported));
if let Err(err) = do_parsed(&parsed, &supported, &dbus) {
print_error_help(&*err, Some(&supported));
}
}
}
}
fn print_error_help(err: &dyn std::error::Error, supported: Option<&SupportedFunctions>) {
check_service("asusd");
println!("\nError: {}\n", err);
print_versions();
println!();
print_laptop_info();
print_info();
if let Some(supported) = supported {
println!();
println!("Supported laptop functions:\n\n{}", supported);
}
}
fn print_versions() {
println!("App 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-platform v{}", rog_platform::VERSION);
}
fn print_laptop_info() {
fn print_info() {
let dmi = sysfs_class::DmiId::default();
let board_name = dmi.board_name().expect("Could not get board_name");
let prod_family = dmi.product_family().expect("Could not get product_family");
println!("Product family: {}", prod_family.trim());
println!("Board name: {}", board_name.trim());
println!("asusctl version: {}", env!("CARGO_PKG_VERSION"));
println!(" Product family: {}", prod_family.trim());
println!(" Board name: {}", board_name.trim());
}
fn check_service(name: &str) -> bool {
@@ -223,9 +207,11 @@ fn handle_anime(
cmd: &AnimeCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if (cmd.command.is_none()
&& cmd.enable.is_none()
&& cmd.boot_enable.is_none()
&& cmd.brightness.is_none())
&& cmd.enable_display.is_none()
&& cmd.enable_powersave_anim.is_none()
&& cmd.brightness.is_none()
&& cmd.image_brightness.is_none()
&& !cmd.clear)
|| cmd.help
{
println!("Missing arg or command\n\n{}", cmd.self_usage());
@@ -233,25 +219,34 @@ fn handle_anime(
println!("\n{}", lst);
}
}
if let Some(anime_turn) = cmd.enable {
dbus.proxies().anime().set_on_off(anime_turn)?;
if let Some(enable) = cmd.enable_display {
dbus.proxies().anime().set_enable_display(enable)?;
}
if let Some(anime_boot) = cmd.boot_enable {
dbus.proxies().anime().set_boot_on_off(anime_boot)?;
if let Some(enable) = cmd.enable_powersave_anim {
dbus.proxies().anime().set_builtins_enabled(enable)?;
}
if let Some(bright) = cmd.brightness {
verify_brightness(bright);
dbus.proxies().anime().set_brightness(bright)?;
}
if let Some(bright) = cmd.image_brightness {
verify_brightness(bright);
dbus.proxies().anime().set_image_brightness(bright)?;
}
let mut anime_type = get_anime_type()?;
if let AnimeType::Unknown = anime_type {
if let Some(model) = cmd.override_type {
anime_type = model;
}
}
if cmd.clear {
let anime_type = get_anime_type()?;
let data = vec![0u8; anime_type.data_length()];
let data = vec![255u8; anime_type.data_length()];
let tmp = AnimeDataBuffer::from_vec(anime_type, data)?;
dbus.proxies().anime().write(tmp)?;
}
if let Some(action) = cmd.command.as_ref() {
let anime_type = get_anime_type()?;
match action {
AnimeActions::Image(image) => {
if image.help_requested() || image.path.is_empty() {
@@ -362,6 +357,23 @@ fn handle_anime(
}
}
}
AnimeActions::SetBuiltins(builtins) => {
if builtins.help_requested() || builtins.set.is_none() {
println!("\nAny unspecified args will be set to default (first shown var)\n");
println!("\n{}", builtins.self_usage());
if let Some(lst) = builtins.self_command_list() {
println!("\n{}", lst);
}
return Ok(());
}
dbus.proxies().anime().set_builtin_animations(
builtins.boot,
builtins.awake,
builtins.sleep,
builtins.shutdown,
)?;
}
}
}
Ok(())
@@ -492,18 +504,16 @@ fn handle_led_power_1_do_1866(
check(power.lightbar, AuraDevRog1::Lightbar);
let data = AuraPowerDev {
x1866: enabled,
x19b6: vec![],
tuf: vec![],
old_rog: enabled,
..Default::default()
};
dbus.proxies().led().set_leds_power(data, true)?;
dbus.proxies().led().set_led_power(data, true)?;
let data = AuraPowerDev {
x1866: disabled,
x19b6: vec![],
tuf: vec![],
old_rog: disabled,
..Default::default()
};
dbus.proxies().led().set_leds_power(data, false)?;
dbus.proxies().led().set_led_power(data, false)?;
Ok(())
}
@@ -531,18 +541,16 @@ fn handle_led_power_1_do_tuf(
check(power.keyboard, AuraDevTuf::Keyboard);
let data = AuraPowerDev {
x1866: vec![],
x19b6: vec![],
tuf: enabled,
..Default::default()
};
dbus.proxies().led().set_leds_power(data, true)?;
dbus.proxies().led().set_led_power(data, true)?;
let data = AuraPowerDev {
x1866: vec![],
x19b6: vec![],
tuf: disabled,
..Default::default()
};
dbus.proxies().led().set_leds_power(data, false)?;
dbus.proxies().led().set_led_power(data, false)?;
Ok(())
}
@@ -580,62 +588,25 @@ fn handle_led_power2(
println!("This option applies only to keyboards with product ID 0x19b6");
}
let mut enabled: Vec<AuraDevRog2> = Vec::new();
let mut disabled: Vec<AuraDevRog2> = Vec::new();
let mut check = |e: Option<bool>, a: AuraDevRog2| {
if let Some(arg) = e {
if arg {
enabled.push(a);
} else {
disabled.push(a);
}
}
let set = |power: &mut KbAuraPowerState, set_to: &AuraPowerStates| {
power.boot = set_to.boot;
power.awake = set_to.awake;
power.sleep = set_to.sleep;
power.shutdown = set_to.shutdown;
};
match pow {
aura_cli::SetAuraEnabled::Boot(arg) => {
check(arg.keyboard, AuraDevRog2::BootKeyb);
check(arg.logo, AuraDevRog2::BootLogo);
check(arg.lightbar, AuraDevRog2::BootBar);
check(arg.lid, AuraDevRog2::AwakeLid);
}
aura_cli::SetAuraEnabled::Sleep(arg) => {
check(arg.keyboard, AuraDevRog2::SleepKeyb);
check(arg.logo, AuraDevRog2::SleepLogo);
check(arg.lightbar, AuraDevRog2::SleepBar);
check(arg.lid, AuraDevRog2::SleepLid);
}
aura_cli::SetAuraEnabled::Awake(arg) => {
check(arg.keyboard, AuraDevRog2::AwakeKeyb);
check(arg.logo, AuraDevRog2::AwakeLogo);
check(arg.lightbar, AuraDevRog2::AwakeBar);
check(arg.lid, AuraDevRog2::AwakeLid);
}
aura_cli::SetAuraEnabled::Shutdown(arg) => {
check(arg.keyboard, AuraDevRog2::ShutdownKeyb);
check(arg.logo, AuraDevRog2::ShutdownLogo);
check(arg.lightbar, AuraDevRog2::ShutdownBar);
check(arg.lid, AuraDevRog2::ShutdownBar);
let mut enabled = dbus.proxies().led().led_power()?;
if let Some(cmd) = &power.command {
match cmd {
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(&mut enabled.rog.keyboard, k),
aura_cli::SetAuraZoneEnabled::Logo(l) => set(&mut enabled.rog.logo, l),
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(&mut enabled.rog.lightbar, l),
aura_cli::SetAuraZoneEnabled::Lid(l) => set(&mut enabled.rog.lid, l),
aura_cli::SetAuraZoneEnabled::RearGlow(r) => set(&mut enabled.rog.rear_glow, r),
}
}
if !enabled.is_empty() {
let data = AuraPowerDev {
tuf: vec![],
x1866: vec![],
x19b6: enabled,
};
dbus.proxies().led().set_leds_power(data, true)?;
}
if !disabled.is_empty() {
let data = AuraPowerDev {
tuf: vec![],
x1866: vec![],
x19b6: disabled,
};
dbus.proxies().led().set_leds_power(data, false)?;
}
dbus.proxies().led().set_led_power(enabled, true)?;
}
Ok(())
@@ -689,7 +660,7 @@ fn handle_fan_curve(
supported: &PlatformProfileFunctions,
cmd: &FanCurveCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if !supported.fan_curves {
if supported.fans.is_empty() {
println!("Fan-curves not supported by either this kernel or by the laptop.");
println!("This requires kernel 5.17 or the fan curve patch listed in the readme.");
return Err(ProfileError::NotSupported.into());
@@ -707,16 +678,22 @@ fn handle_fan_curve(
return Ok(());
}
if (cmd.enabled.is_some() || cmd.fan.is_some() || cmd.data.is_some())
if (cmd.enable_fan_curves.is_some() || cmd.fan.is_some() || cmd.data.is_some())
&& cmd.mod_profile.is_none()
{
println!("--enabled, --fan, and --data options require --mod-profile");
println!(
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
--mod-profile"
);
return Ok(());
}
if cmd.get_enabled {
let res = dbus.proxies().profile().enabled_fan_profiles()?;
println!("{:?}", res);
let profile = dbus.proxies().profile().active_profile()?;
let curves = dbus.proxies().profile().fan_curve_data(profile)?;
for curve in curves.iter() {
println!("{}", String::from(curve));
}
}
if cmd.default {
@@ -724,16 +701,29 @@ fn handle_fan_curve(
}
if let Some(profile) = cmd.mod_profile {
if cmd.enabled.is_none() && cmd.data.is_none() {
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
let data = dbus.proxies().profile().fan_curve_data(profile)?;
let data = toml::to_string(&data)?;
println!("\nFan curves for {:?}\n\n{}", profile, data);
}
if let Some(enabled) = cmd.enabled {
if let Some(enabled) = cmd.enable_fan_curves {
dbus.proxies()
.profile()
.set_fan_curve_enabled(profile, enabled)?;
.set_fan_curves_enabled(profile, enabled)?;
}
if let Some(enabled) = cmd.enable_fan_curve {
if let Some(fan) = cmd.fan {
dbus.proxies()
.profile()
.set_profile_fan_curve_enabled(profile, fan, enabled)?;
} else {
println!(
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
--mod-profile"
);
}
}
if let Some(mut curve) = cmd.data.clone() {

View File

@@ -6,13 +6,16 @@ use rog_profiles::{FanCurvePU, Profile};
pub struct ProfileCommand {
#[options(help = "print help message")]
pub help: bool,
#[options(help = "toggle to next profile in list")]
pub next: bool,
#[options(help = "list available profiles")]
pub list: bool,
#[options(help = "get profile")]
pub profile_get: bool,
#[options(meta = "", help = "set the active profile")]
pub profile_set: Option<Profile>,
}
@@ -24,6 +27,7 @@ pub struct FanCurveCommand {
#[options(help = "get enabled fan profiles")]
pub get_enabled: bool,
#[options(help = "set the active profile's fan curve to default")]
pub default: bool,
@@ -32,21 +36,31 @@ pub struct FanCurveCommand {
help = "profile to modify fan-curve for. Shows data if no options provided"
)]
pub mod_profile: Option<Profile>,
#[options(
meta = "",
help = "enable or disable <true/false> fan curve. `mod-profile` required"
help = "enable or disable <true/false> fan all curves for a profile. `--mod_profile` \
required"
)]
pub enabled: Option<bool>,
pub enable_fan_curves: Option<bool>,
#[options(
meta = "",
help = "select fan <cpu/gpu> to modify. `mod-profile` required"
help = "enable or disable <true/false> a single fan curve for a profile. `--mod_profile` \
and `--fan` required"
)]
pub enable_fan_curve: Option<bool>,
#[options(
meta = "",
help = "select fan <cpu/gpu/mid> to modify. `--mod_profile` required"
)]
pub fan: Option<FanCurvePU>,
#[options(
meta = "",
help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%.
`--mod-profile` required. If '%' is omitted the fan range is 0-255"
help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%. \
`--mod-profile` required. If '%' is omitted the fan range is 0-255"
)]
pub data: Option<CurveData>,
}

View File

@@ -1,15 +1,11 @@
[package]
name = "daemon-user"
name = "asusd-user"
license = "MPL-2.0"
version.workspace = true
authors = ["Luke D Jones <luke@ljones.dev>"]
edition = "2021"
description = "Usermode daemon for user settings, anime, per-key lighting"
[lib]
name = "rog_user"
path = "src/lib.rs"
[[bin]]
name = "asusd-user"
path = "src/daemon.rs"

View File

@@ -136,8 +136,16 @@ impl Default for ConfigAura {
let mut seq = AuraSequences::new(false);
let mut key = Effect::Breathe(Breathe::new(
LedCode::W,
Colour(255, 0, 20),
Colour(20, 255, 0),
Colour {
r: 255,
g: 0,
b: 20,
},
Colour {
r: 20,
g: 255,
b: 0,
},
Speed::Low,
));
@@ -151,20 +159,25 @@ impl Default for ConfigAura {
let key = Effect::Breathe(Breathe::new(
LedCode::F,
Colour(255, 0, 0),
Colour(255, 0, 0),
Colour { r: 255, g: 0, b: 0 },
Colour { r: 255, g: 0, b: 0 },
Speed::High,
));
seq.push(key);
let mut key = Effect::Static(Static::new(LedCode::RCtrl, Colour(0, 0, 255)));
let mut key = Effect::Static(Static::new(LedCode::RCtrl, Colour { r: 0, g: 0, b: 255 }));
seq.push(key.clone());
key.set_led(LedCode::LCtrl);
seq.push(key.clone());
key.set_led(LedCode::Esc);
seq.push(key);
let key = Effect::DoomFlicker(DoomFlicker::new(LedCode::N9, Colour(0, 0, 255), 80, 40));
let key = Effect::DoomFlicker(DoomFlicker::new(
LedCode::N9,
Colour { r: 0, g: 0, b: 255 },
80,
40,
));
seq.push(key);
Self {

View File

@@ -22,22 +22,18 @@ pub struct Timer {
/// animation loop count
count: u64,
/// Used only for `TimeType::Timer`, milliseonds to fade the image in for
fade_in: Option<u64>,
fade_in: u64,
/// Used only for `TimeType::Timer`, milliseonds to fade the image out for
fade_out: Option<u64>,
fade_out: 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);
if time.fade_in != 0 && time.fade_out != 0 {
let fade_in = Duration::from_millis(time.fade_in);
let fade_out = Duration::from_millis(time.fade_out);
let show_for = if time.count != 0 {
Some(Duration::from_millis(time.count))
} else {
@@ -360,13 +356,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().set_on_off(on).ok();
self.client.proxies().anime().set_enable_display(on).ok();
// 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().set_on_off(on).ok();
self.client.proxies().anime().set_enable_display(on).ok();
}
Ok(())
}

View File

@@ -3,14 +3,14 @@ use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex};
use asusd_user::config::*;
use asusd_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
use asusd_user::DBUS_NAME;
use config_traits::{StdConfig, StdConfigLoad};
use rog_anime::usb::get_anime_type;
use rog_aura::aura_detection::LaptopLedData;
use rog_aura::layouts::KeyLayout;
use rog_dbus::RogDbusClientBlocking;
use rog_user::config::*;
use rog_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
use rog_user::DBUS_NAME;
use smol::Executor;
use zbus::Connection;
@@ -28,7 +28,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
.init();
println!(" user daemon v{}", rog_user::VERSION);
println!(" user daemon v{}", asusd_user::VERSION);
println!(" rog-anime v{}", rog_anime::VERSION);
println!(" rog-dbus v{}", rog_dbus::VERSION);
println!("rog-platform v{}", rog_platform::VERSION);

View File

@@ -23,7 +23,10 @@
use zbus::dbus_proxy;
#[dbus_proxy(interface = "org.asuslinux.Daemon")]
#[dbus_proxy(
interface = "org.asuslinux.Daemon",
default_path = "/org/asuslinux/Anime"
)]
trait Daemon {
/// InsertAsusGif method
fn insert_asus_gif(

View File

@@ -1,5 +1,5 @@
[package]
name = "daemon"
name = "asusd"
license = "MPL-2.0"
version.workspace = true
readme = "README.md"
@@ -9,10 +9,6 @@ homepage = "https://gitlab.com/asus-linux/asus-nb-ctrl"
description = "A daemon app for ASUS GX502 and similar laptops to control missing features"
edition = "2021"
[lib]
name = "daemon"
path = "src/lib.rs"
[[bin]]
name = "asusd"
path = "src/daemon.rs"

View File

@@ -8,6 +8,7 @@ pub struct Config {
/// Save charge limit for restoring on boot
pub bat_charge_limit: u8,
pub panel_od: bool,
pub mini_led_mode: bool,
pub disable_nvidia_powerd_on_battery: bool,
pub ac_command: String,
pub bat_command: String,
@@ -18,6 +19,7 @@ impl StdConfig for Config {
Config {
bat_charge_limit: 100,
panel_od: false,
mini_led_mode: false,
disable_nvidia_powerd_on_battery: true,
ac_command: String::new(),
bat_command: String::new(),
@@ -33,21 +35,24 @@ impl StdConfig for Config {
}
}
impl StdConfigLoad2<Config455, Config458> for Config {}
impl StdConfigLoad2<Config458, Config462> for Config {}
#[derive(Deserialize, Serialize, Default)]
#[serde(default)]
pub struct Config455 {
#[derive(Deserialize, Serialize)]
pub struct Config462 {
/// Save charge limit for restoring on boot
pub bat_charge_limit: u8,
pub panel_od: bool,
pub disable_nvidia_powerd_on_battery: bool,
pub ac_command: String,
pub bat_command: String,
}
impl From<Config455> for Config {
fn from(c: Config455) -> Self {
impl From<Config462> for Config {
fn from(c: Config462) -> Self {
Self {
bat_charge_limit: c.bat_charge_limit,
panel_od: c.panel_od,
mini_led_mode: false,
disable_nvidia_powerd_on_battery: true,
ac_command: String::new(),
bat_command: String::new(),
@@ -55,7 +60,7 @@ impl From<Config455> for Config {
}
}
#[derive(Deserialize, Serialize, Default)]
#[derive(Deserialize, Serialize)]
pub struct Config458 {
/// Save charge limit for restoring on boot
pub bat_charge_limit: u8,
@@ -69,6 +74,7 @@ impl From<Config458> for Config {
Self {
bat_charge_limit: c.bat_charge_limit,
panel_od: c.panel_od,
mini_led_mode: false,
disable_nvidia_powerd_on_battery: true,
ac_command: c.ac_command,
bat_command: c.bat_command,

View File

@@ -2,78 +2,12 @@ use std::time::Duration;
use config_traits::{StdConfig, StdConfigLoad2};
use rog_anime::error::AnimeError;
use rog_anime::{ActionData, ActionLoader, AnimTime, AnimeType, Fade, Vec2};
use rog_anime::usb::Brightness;
use rog_anime::{ActionData, ActionLoader, AnimTime, Animations, AnimeType, Fade, Vec2};
use serde_derive::{Deserialize, Serialize};
const CONFIG_FILE: &str = "anime.ron";
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV341 {
pub system: Option<ActionLoader>,
pub boot: Option<ActionLoader>,
pub suspend: Option<ActionLoader>,
pub shutdown: Option<ActionLoader>,
}
impl From<AnimeConfigV341> for AnimeConfig {
fn from(c: AnimeConfigV341) -> AnimeConfig {
AnimeConfig {
system: if let Some(ani) = c.system {
vec![ani]
} else {
vec![]
},
boot: if let Some(ani) = c.boot {
vec![ani]
} else {
vec![]
},
wake: if let Some(ani) = c.suspend {
vec![ani]
} else {
vec![]
},
shutdown: if let Some(ani) = c.shutdown.clone() {
vec![ani]
} else {
vec![]
},
sleep: if let Some(ani) = c.shutdown.clone() {
vec![ani]
} else {
vec![]
},
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV352 {
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
}
impl From<AnimeConfigV352> for AnimeConfig {
fn from(c: AnimeConfigV352) -> AnimeConfig {
AnimeConfig {
system: c.system,
boot: c.boot,
wake: c.wake,
sleep: c.shutdown.clone(),
shutdown: c.shutdown,
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV460 {
pub system: Vec<ActionLoader>,
@@ -92,9 +26,32 @@ impl From<AnimeConfigV460> for AnimeConfig {
wake: c.wake,
sleep: c.sleep,
shutdown: c.shutdown,
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
..Default::default()
}
}
}
#[derive(Deserialize, Serialize, Debug)]
pub struct AnimeConfigV5 {
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
pub awake_enabled: bool,
pub boot_anim_enabled: bool,
}
impl From<AnimeConfigV5> for AnimeConfig {
fn from(c: AnimeConfigV5) -> AnimeConfig {
AnimeConfig {
system: c.system,
boot: c.boot,
wake: c.wake,
sleep: c.sleep,
shutdown: c.shutdown,
..Default::default()
}
}
}
@@ -150,27 +107,33 @@ impl AnimeConfigCached {
/// Config for base system actions for the anime display
#[derive(Deserialize, Serialize, Debug)]
pub struct AnimeConfig {
pub model_override: Option<AnimeType>,
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
pub awake_enabled: bool,
pub boot_anim_enabled: bool,
pub display_enabled: bool,
pub display_brightness: Brightness,
pub builtin_anims_enabled: bool,
pub builtin_anims: Animations,
}
impl Default for AnimeConfig {
fn default() -> Self {
AnimeConfig {
model_override: None,
system: Vec::new(),
boot: Vec::new(),
wake: Vec::new(),
sleep: Vec::new(),
shutdown: Vec::new(),
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
display_enabled: true,
display_brightness: Brightness::Med,
builtin_anims_enabled: true,
builtin_anims: Animations::default(),
}
}
}
@@ -189,7 +152,7 @@ impl StdConfig for AnimeConfig {
}
}
impl StdConfigLoad2<AnimeConfigV341, AnimeConfigV352> for AnimeConfig {}
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV5> for AnimeConfig {}
impl AnimeConfig {
// fn clamp_config_brightness(mut config: &mut AnimeConfig) {
@@ -247,8 +210,7 @@ impl AnimeConfig {
time: AnimTime::Infinite,
}],
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
..Default::default()
}
}
}

View File

@@ -3,7 +3,6 @@ pub mod config;
pub mod trait_impls;
use std::convert::TryFrom;
use std::error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::sleep;
@@ -11,7 +10,7 @@ use std::thread::sleep;
use ::zbus::export::futures_util::lock::Mutex;
use log::{error, info, warn};
use rog_anime::error::AnimeError;
use rog_anime::usb::{get_anime_type, pkt_for_flush, pkts_for_init};
use rog_anime::usb::{get_anime_type, pkt_flush, pkt_set_enable_powersave_anim, pkts_for_init};
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType};
use rog_platform::hid_raw::HidRaw;
use rog_platform::supported::AnimeSupportedFunctions;
@@ -25,12 +24,37 @@ impl GetSupported for CtrlAnime {
type A = AnimeSupportedFunctions;
fn get_supported() -> Self::A {
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
if USBRaw::new(0x193b).is_ok() {
AnimeSupportedFunctions(true)
} else {
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
}
}
}
enum Node {
Usb(USBRaw),
Hid(HidRaw),
}
impl Node {
pub fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
// TODO: map and pass on errors
match self {
Node::Usb(u) => {
u.write_bytes(message).ok();
}
Node::Hid(h) => {
h.write_bytes(message).ok();
}
}
Ok(())
}
}
pub struct CtrlAnime {
node: USBRaw,
// node: HidRaw,
node: Node,
anime_type: AnimeType,
cache: AnimeConfigCached,
config: AnimeConfig,
@@ -42,11 +66,26 @@ pub struct CtrlAnime {
impl CtrlAnime {
#[inline]
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, Box<dyn Error>> {
let node = USBRaw::new(0x193b)?;
let anime_type = get_anime_type()?;
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, RogError> {
let usb = USBRaw::new(0x193b).ok();
let hid = HidRaw::new("193b").ok();
let node = if usb.is_some() {
unsafe { Node::Usb(usb.unwrap_unchecked()) }
} else if hid.is_some() {
unsafe { Node::Hid(hid.unwrap_unchecked()) }
} else {
return Err(RogError::Anime(AnimeError::NoDevice));
};
info!("Device has an AniMe Matrix display");
let mut anime_type = get_anime_type()?;
if let AnimeType::Unknown = anime_type {
if let Some(model) = config.model_override {
warn!("Overriding the Animatrix type as {model:?}");
anime_type = model;
}
}
info!("Device has an AniMe Matrix display: {anime_type:?}");
let mut cache = AnimeConfigCached::default();
cache.init_from_config(&config, anime_type)?;
@@ -70,12 +109,21 @@ impl CtrlAnime {
///
/// Because this also writes to the usb device, other write tries (display
/// only) *must* get the mutex lock and set the `thread_exit` atomic.
fn run_thread(inner: Arc<Mutex<CtrlAnime>>, actions: Vec<ActionData>, mut once: bool) {
async fn run_thread(inner: Arc<Mutex<CtrlAnime>>, actions: Vec<ActionData>, mut once: bool) {
if actions.is_empty() {
warn!("AniMe system actions was empty");
return;
}
if let Some(lock) = inner.try_lock() {
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
}
// Loop rules:
// - Lock the mutex **only when required**. That is, the lock must be held for
// the shortest duration possible.
@@ -209,7 +257,7 @@ impl CtrlAnime {
for row in &data {
self.node.write_bytes(row)?;
}
self.node.write_bytes(&pkt_for_flush())?;
self.node.write_bytes(&pkt_flush())?;
Ok(())
}

View File

@@ -0,0 +1,300 @@
use std::sync::atomic::Ordering;
use std::sync::Arc;
use async_trait::async_trait;
use config_traits::StdConfig;
use log::warn;
use rog_anime::usb::{
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
pkt_set_enable_powersave_anim, AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness,
};
use rog_anime::{AnimeDataBuffer, DeviceState};
use zbus::export::futures_util::lock::Mutex;
use zbus::{dbus_interface, Connection, SignalContext};
use super::CtrlAnime;
use crate::error::RogError;
pub(super) const ZBUS_PATH: &str = "/org/asuslinux/Anime";
#[derive(Clone)]
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
/// The struct with the main dbus methods requires this trait
#[async_trait]
impl crate::ZbusRun for CtrlAnimeZbus {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
}
}
// None of these calls can be guarnateed to succeed unless we loop until okay
// If the try_lock *does* succeed then any other thread trying to lock will not
// grab it until we finish.
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlAnimeZbus {
/// Writes a data stream of length. Will force system thread to exit until
/// it is restarted
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
lock.write_data_buffer(input).map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
err
})?;
Ok(())
}
/// Set the global AniMe brightness
async fn set_image_brightness(&self, bright: f32) {
let mut lock = self.0.lock().await;
let mut bright = bright;
if bright < 0.0 {
bright = 0.0;
} else if bright > 1.0 {
bright = 1.0;
}
lock.config.brightness = bright;
lock.config.write();
}
/// Set base brightness level
// TODO: enum for brightness
async fn set_brightness(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
brightness: Brightness,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_brightness(brightness))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.display_brightness = brightness;
lock.config.write();
Self::notify_device_state(
&ctxt,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Enable the builtin animations or not. This is quivalent to "Powersave
/// animations" in Armory crate
async fn set_builtins_enabled(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: bool,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(enabled))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.builtin_anims_enabled = enabled;
lock.config.write();
if enabled {
lock.thread_exit.store(true, Ordering::Release);
}
Self::notify_device_state(
&ctxt,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Set which builtin animation is used for each stage
async fn set_builtin_animations(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
boot: AnimBooting,
awake: AnimAwake,
sleep: AnimSleeping,
shutdown: AnimShutdown,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(true))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.node
.write_bytes(&pkt_set_builtin_animations(boot, awake, sleep, shutdown))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.builtin_anims.boot = boot;
lock.config.builtin_anims.sleep = sleep;
lock.config.builtin_anims.awake = awake;
lock.config.builtin_anims.shutdown = shutdown;
lock.config.write();
Self::notify_device_state(
&ctxt,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Set whether the AniMe is enabled at all
async fn set_enable_display(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: bool,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_display(enabled))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.display_enabled = enabled;
lock.config.write();
Self::notify_device_state(
&ctxt,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// The main loop is the base system set action if the user isn't running
/// the user daemon
async fn run_main_loop(&self, start: bool) {
if start {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false).await;
}
}
/// Get the device state as stored by asusd
// #[dbus_interface(property)]
async fn device_state(&self) -> DeviceState {
let lock = self.0.lock().await;
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
}
}
/// Notify listeners of the status of AniMe LED power and factory
/// system-status animations
#[dbus_interface(signal)]
async fn notify_device_state(ctxt: &SignalContext<'_>, data: DeviceState) -> zbus::Result<()>;
}
#[async_trait]
impl crate::CtrlTask for CtrlAnimeZbus {
fn zbus_path() -> &'static str {
ZBUS_PATH
}
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
let inner1 = self.0.clone();
let inner2 = self.0.clone();
let inner3 = self.0.clone();
let inner4 = self.0.clone();
self.create_sys_event_tasks(
move || {
// on_sleep
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true).await;
}
},
move || {
// on_wake
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true).await;
}
},
move || {
// on_shutdown
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true).await;
}
},
move || {
// on_boot
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true).await;
}
},
)
.await;
Ok(())
}
}
#[async_trait]
impl crate::Reloadable for CtrlAnimeZbus {
async fn reload(&mut self) -> Result<(), RogError> {
if let Some(lock) = self.0.try_lock() {
let anim = &lock.config.builtin_anims;
lock.node
.write_bytes(&pkt_set_enable_display(lock.config.display_enabled))?;
lock.node.write_bytes(&pkt_set_enable_powersave_anim(
lock.config.builtin_anims_enabled,
))?;
lock.node.write_bytes(&pkt_set_builtin_animations(
anim.boot,
anim.awake,
anim.sleep,
anim.shutdown,
))?;
if lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false))
.ok();
}
let action = lock.cache.boot.clone();
CtrlAnime::run_thread(self.0.clone(), action, true).await;
}
Ok(())
}
}

View File

@@ -1,9 +1,12 @@
use std::collections::{BTreeMap, HashSet};
use config_traits::{StdConfig, StdConfigLoad};
use rog_aura::aura_detection::LaptopLedData;
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
use log::{debug, warn};
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
use rog_aura::power::AuraPower;
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
use rog_platform::hid_raw::HidRaw;
use serde_derive::{Deserialize, Serialize};
const CONFIG_FILE: &str = "aura.ron";
@@ -15,22 +18,19 @@ const CONFIG_FILE: &str = "aura.ron";
pub enum AuraPowerConfig {
AuraDevTuf(HashSet<AuraDevTuf>),
AuraDevRog1(HashSet<AuraDevRog1>),
AuraDevRog2(HashSet<AuraDevRog2>),
AuraDevRog2(AuraPower),
}
impl AuraPowerConfig {
/// Invalid for TUF laptops
pub fn to_bytes(control: &Self) -> [u8; 3] {
pub fn to_bytes(control: &Self) -> [u8; 4] {
match control {
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0],
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0, 0],
AuraPowerConfig::AuraDevRog1(c) => {
let c: Vec<AuraDevRog1> = c.iter().copied().collect();
AuraDevRog1::to_bytes(&c)
}
AuraPowerConfig::AuraDevRog2(c) => {
let c: Vec<AuraDevRog2> = c.iter().copied().collect();
AuraDevRog2::to_bytes(&c)
}
AuraPowerConfig::AuraDevRog2(c) => c.to_bytes(),
}
}
@@ -78,13 +78,9 @@ impl AuraPowerConfig {
}
}
pub fn set_0x19b6(&mut self, power: AuraDevRog2, on: bool) {
pub fn set_0x19b6(&mut self, power: AuraPower) {
if let Self::AuraDevRog2(p) = self {
if on {
p.insert(power);
} else {
p.remove(&power);
}
*p = power;
}
}
}
@@ -94,18 +90,15 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
match config {
AuraPowerConfig::AuraDevTuf(d) => AuraPowerDev {
tuf: d.iter().copied().collect(),
x1866: vec![],
x19b6: vec![],
..Default::default()
},
AuraPowerConfig::AuraDevRog1(d) => AuraPowerDev {
tuf: vec![],
x1866: d.iter().copied().collect(),
x19b6: vec![],
old_rog: d.iter().copied().collect(),
..Default::default()
},
AuraPowerConfig::AuraDevRog2(d) => AuraPowerDev {
tuf: vec![],
x1866: vec![],
x19b6: d.iter().copied().collect(),
rog: d.clone(),
..Default::default()
},
}
}
@@ -123,9 +116,17 @@ pub struct AuraConfig {
}
impl StdConfig for AuraConfig {
/// Detect the keyboard type and load from default DB if data available
fn new() -> Self {
// Self::create_default(AuraDevice::X19b6, &LaptopLedData::get_data())
panic!("AuraConfig::new() should not be used, use AuraConfig::create_default() instead");
warn!("AuraConfig: creating new config");
let mut prod_id = AuraDevice::Unknown;
for prod in ASUS_KEYBOARD_DEVICES {
if HidRaw::new(prod.into()).is_ok() {
prod_id = prod;
break;
}
}
Self::from_default_support(prod_id, &LaptopLedData::get_data())
}
fn config_dir() -> std::path::PathBuf {
@@ -140,23 +141,10 @@ impl StdConfig for AuraConfig {
impl StdConfigLoad for AuraConfig {}
impl AuraConfig {
pub fn create_default(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
// create a default config here
let enabled = if prod_id == AuraDevice::X19b6 {
AuraPowerConfig::AuraDevRog2(HashSet::from([
AuraDevRog2::BootLogo,
AuraDevRog2::BootKeyb,
AuraDevRog2::SleepLogo,
AuraDevRog2::SleepKeyb,
AuraDevRog2::AwakeLogo,
AuraDevRog2::AwakeKeyb,
AuraDevRog2::ShutdownLogo,
AuraDevRog2::ShutdownKeyb,
AuraDevRog2::BootBar,
AuraDevRog2::AwakeBar,
AuraDevRog2::SleepBar,
AuraDevRog2::ShutdownBar,
]))
AuraPowerConfig::AuraDevRog2(AuraPower::new_all_on())
} else if prod_id == AuraDevice::Tuf {
AuraPowerConfig::AuraDevTuf(HashSet::from([
AuraDevTuf::Awake,
@@ -183,6 +171,7 @@ impl AuraConfig {
};
for n in &support_data.basic_modes {
debug!("AuraConfig: creating default for {n}");
config
.builtins
.insert(*n, AuraEffect::default_with_mode(*n));
@@ -260,10 +249,15 @@ mod tests {
#[test]
fn set_multizone_4key_config() {
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
let mut config =
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
let effect = AuraEffect {
colour1: Colour(0xff, 0x00, 0xff),
colour1: Colour {
r: 0xff,
g: 0x00,
b: 0xff,
},
zone: AuraZone::Key1,
..Default::default()
};
@@ -272,21 +266,33 @@ mod tests {
assert!(config.multizone.is_some());
let effect = AuraEffect {
colour1: Colour(0x00, 0xff, 0xff),
colour1: Colour {
r: 0x00,
g: 0xff,
b: 0xff,
},
zone: AuraZone::Key2,
..Default::default()
};
config.set_builtin(effect);
let effect = AuraEffect {
colour1: Colour(0xff, 0xff, 0x00),
colour1: Colour {
r: 0xff,
g: 0xff,
b: 0x00,
},
zone: AuraZone::Key3,
..Default::default()
};
config.set_builtin(effect);
let effect = AuraEffect {
colour1: Colour(0x00, 0xff, 0x00),
colour1: Colour {
r: 0x00,
g: 0xff,
b: 0x00,
},
zone: AuraZone::Key4,
..Default::default()
};
@@ -298,15 +304,44 @@ mod tests {
let res = config.multizone.unwrap();
let sta = res.get(&AuraModeNum::Static).unwrap();
assert_eq!(sta.len(), 4);
assert_eq!(sta[0].colour1, Colour(0xff, 0x00, 0xff));
assert_eq!(sta[1].colour1, Colour(0x00, 0xff, 0xff));
assert_eq!(sta[2].colour1, Colour(0xff, 0xff, 0x00));
assert_eq!(sta[3].colour1, Colour(0x00, 0xff, 0x00));
assert_eq!(
sta[0].colour1,
Colour {
r: 0xff,
g: 0x00,
b: 0xff
}
);
assert_eq!(
sta[1].colour1,
Colour {
r: 0x00,
g: 0xff,
b: 0xff
}
);
assert_eq!(
sta[2].colour1,
Colour {
r: 0xff,
g: 0xff,
b: 0x00
}
);
assert_eq!(
sta[3].colour1,
Colour {
r: 0x00,
g: 0xff,
b: 0x00
}
);
}
#[test]
fn set_multizone_multimode_config() {
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
let mut config =
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
let effect = AuraEffect {
zone: AuraZone::Key1,

View File

@@ -20,9 +20,6 @@ impl GetSupported for CtrlKbdLed {
fn get_supported() -> Self::A {
// let mode = <&str>::from(&<AuraModes>::from(*mode));
let laptop = LaptopLedData::get_data();
let stock_led_modes = laptop.basic_modes;
let multizone_led_mode = laptop.basic_zones;
let advanced_type = laptop.advanced_type;
let mut prod_id = AuraDevice::Unknown;
for prod in ASUS_KEYBOARD_DEVICES {
@@ -42,14 +39,15 @@ impl GetSupported for CtrlKbdLed {
LedSupportedFunctions {
dev_id: prod_id,
brightness: rgb.is_ok(),
basic_modes: stock_led_modes,
basic_zones: multizone_led_mode,
advanced_type: advanced_type.into(),
basic_modes: laptop.basic_modes,
basic_zones: laptop.basic_zones,
advanced_type: laptop.advanced_type.into(),
power_zones: laptop.power_zones,
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd)]
#[derive(Debug, PartialEq, Eq)]
pub enum LEDNode {
KbdLed(KeyboardLed),
Rog(HidRaw),
@@ -114,14 +112,37 @@ impl CtrlKbdLed {
LEDNode::None
};
let config_init = AuraConfig::create_default(led_prod, &supported_modes);
let mut config = config_init.clone().load();
// Do updates of supported modes if required
for mode in &config_init.builtins {
if !config.builtins.contains_key(mode.0) {
config.builtins.insert(*mode.0, mode.1.clone());
// New loads data fromt he DB also
let mut config_init = AuraConfig::new();
let mut config_loaded = config_init.clone().load();
// update the initialised data with what we loaded from disk
for mode in &mut config_init.builtins {
// update init values from loaded values if they exist
if let Some(loaded) = config_loaded.builtins.get(mode.0) {
*mode.1 = loaded.clone();
}
}
// Then replace just incase the initialised data contains new modes added
config_loaded.builtins = config_init.builtins;
if let (Some(mut multizone_init), Some(multizone_loaded)) =
(config_init.multizone, config_loaded.multizone.as_mut())
{
for mode in multizone_init.iter_mut() {
// update init values from loaded values if they exist
if let Some(loaded) = multizone_loaded.get(mode.0) {
let mut new_set = Vec::new();
// only reuse a zone mode if the mode is supported
for mode in loaded {
if supported_modes.basic_modes.contains(&mode.mode) {
new_set.push(mode.clone());
}
}
*mode.1 = new_set;
}
}
*multizone_loaded = multizone_init;
}
let ctrl = CtrlKbdLed {
led_prod,
@@ -130,7 +151,7 @@ impl CtrlKbdLed {
supported_modes,
flip_effect_write: false,
per_key_mode_active: false,
config,
config: config_loaded,
};
Ok(ctrl)
}
@@ -179,7 +200,7 @@ impl CtrlKbdLed {
}
} 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]];
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
hid_raw.write_bytes(&message)?;
hid_raw.write_bytes(&LED_SET)?;
@@ -204,7 +225,11 @@ impl CtrlKbdLed {
self.write_mode(&effect)?;
self.config.read(); // refresh config if successful
self.config.set_builtin(effect);
if self.config.brightness == LedBrightness::Off {
self.config.brightness = LedBrightness::Med;
}
self.config.write();
self.set_brightness(self.config.brightness)?;
Ok(())
}
@@ -212,6 +237,11 @@ impl CtrlKbdLed {
/// write the raw factory mode packets - when doing this it is expected that
/// only the first `Vec` (`effect[0]`) is valid.
pub fn write_effect_block(&mut self, effect: &UsbPackets) -> Result<(), RogError> {
if self.config.brightness == LedBrightness::Off {
self.config.brightness = LedBrightness::Med;
self.config.write();
}
let pkt_type = effect[0][1];
const PER_KEY_TYPE: u8 = 0xbc;
@@ -287,9 +317,9 @@ impl CtrlKbdLed {
let buf = [
1,
mode.mode as u8,
mode.colour1.0,
mode.colour1.1,
mode.colour1.2,
mode.colour1.r,
mode.colour1.g,
mode.colour1.b,
mode.speed as u8,
];
platform.set_kbd_rgb_mode(&buf)?;
@@ -373,7 +403,7 @@ impl CtrlKbdLed {
#[cfg(test)]
mod tests {
use rog_aura::aura_detection::LaptopLedData;
use rog_aura::aura_detection::{LaptopLedData, PowerZones};
use rog_aura::usb::AuraDevice;
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
use rog_platform::keyboard_led::KeyboardLed;
@@ -386,13 +416,14 @@ mod tests {
// #[ignore = "Must be manually run due to detection stage"]
fn check_set_mode_errors() {
// Checking to ensure set_mode errors when unsupported modes are tried
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
let supported_modes = LaptopLedData {
board_name: String::new(),
layout_name: "ga401".to_owned(),
basic_modes: vec![AuraModeNum::Static],
basic_zones: vec![],
advanced_type: rog_aura::AdvancedAuraType::None,
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
};
let mut controller = CtrlKbdLed {
led_prod: AuraDevice::X19b6,
@@ -405,7 +436,11 @@ mod tests {
};
let mut effect = AuraEffect {
colour1: Colour(0xff, 0x00, 0xff),
colour1: Colour {
r: 0xff,
g: 0x00,
b: 0xff,
},
zone: AuraZone::None,
..Default::default()
};
@@ -449,13 +484,14 @@ mod tests {
#[test]
fn create_multizone_if_no_config() {
// Checking to ensure set_mode errors when unsupported modes are tried
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
let supported_modes = LaptopLedData {
board_name: String::new(),
layout_name: "ga401".to_owned(),
basic_modes: vec![AuraModeNum::Static],
basic_zones: vec![],
advanced_type: rog_aura::AdvancedAuraType::None,
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
};
let mut controller = CtrlKbdLed {
led_prod: AuraDevice::X19b6,
@@ -487,13 +523,14 @@ mod tests {
#[test]
fn next_mode_create_multizone_if_no_config() {
// Checking to ensure set_mode errors when unsupported modes are tried
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
let supported_modes = LaptopLedData {
board_name: String::new(),
layout_name: "ga401".to_owned(),
basic_modes: vec![AuraModeNum::Static],
basic_zones: vec![AuraZone::Key1, AuraZone::Key2],
advanced_type: rog_aura::AdvancedAuraType::None,
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
};
let mut controller = CtrlKbdLed {
led_prod: AuraDevice::X19b6,

View File

@@ -3,9 +3,9 @@ use std::sync::Arc;
use async_trait::async_trait;
use config_traits::StdConfig;
use log::{error, info, warn};
use log::{debug, error, info, warn};
use rog_aura::advanced::UsbPackets;
use rog_aura::usb::AuraPowerDev;
use rog_aura::usb::{AuraDevice, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
use zbus::export::futures_util::StreamExt;
@@ -53,34 +53,8 @@ impl CtrlKbdLedZbus {
/// Set a variety of states, input is array of enum.
/// `enabled` sets if the sent array should be disabled or enabled
///
/// ```text
/// pub struct AuraPowerDev {
/// pub x1866: Vec<AuraDev1866>,
/// pub x19b6: Vec<AuraDev19b6>,
/// }
/// pub enum AuraDev1866 {
/// Awake,
/// Keyboard,
/// Lightbar,
/// Boot,
/// Sleep,
/// }
/// enum AuraDev19b6 {
/// BootLogo,
/// BootKeyb,
/// AwakeLogo,
/// AwakeKeyb,
/// SleepLogo,
/// SleepKeyb,
/// ShutdownLogo,
/// ShutdownKeyb,
/// AwakeBar,
/// BootBar,
/// SleepBar,
/// ShutdownBar,
/// }
/// ```
async fn set_leds_power(
/// For Modern ROG devices the "enabled" flag is ignored.
async fn set_led_power(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
options: AuraPowerDev,
@@ -90,12 +64,10 @@ impl CtrlKbdLedZbus {
for p in options.tuf {
ctrl.config.enabled.set_tuf(p, enabled);
}
for p in options.x1866 {
for p in options.old_rog {
ctrl.config.enabled.set_0x1866(p, enabled);
}
for p in options.x19b6 {
ctrl.config.enabled.set_0x19b6(p, enabled);
}
ctrl.config.enabled.set_0x19b6(options.rog);
ctrl.config.write();
@@ -122,6 +94,11 @@ impl CtrlKbdLedZbus {
e
})?;
ctrl.set_brightness(ctrl.config.brightness).map_err(|e| {
warn!("{}", e);
e
})?;
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
Self::notify_led(&ctxt, mode.clone())
.await
@@ -188,9 +165,15 @@ impl CtrlKbdLedZbus {
Ok(())
}
/// Return the device type for this Aura keyboard
async fn device_type(&self) -> AuraDevice {
let ctrl = self.0.lock().await;
ctrl.led_prod
}
// As property doesn't work for AuraPowerDev (complexity of serialization?)
// #[dbus_interface(property)]
async fn leds_enabled(&self) -> AuraPowerDev {
async fn led_power(&self) -> AuraPowerDev {
let ctrl = self.0.lock().await;
AuraPowerDev::from(&ctrl.config.enabled)
}
@@ -251,7 +234,6 @@ impl CtrlTask for CtrlKbdLedZbus {
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
} else if start {
info!("CtrlKbdLedTask saving last brightness");
Self::update_config(&mut lock)
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
@@ -298,11 +280,11 @@ impl CtrlTask for CtrlKbdLedZbus {
let ctrl2 = self.0.clone();
let ctrl = self.0.lock().await;
let mut watch = ctrl.kd_brightness.monitor_brightness()?;
let watch = ctrl.kd_brightness.monitor_brightness()?;
tokio::spawn(async move {
let mut buffer = [0; 32];
watch
.event_stream(&mut buffer)
.into_event_stream(&mut buffer)
.unwrap()
.for_each(|_| async {
if let Some(lock) = ctrl2.try_lock() {
@@ -320,7 +302,9 @@ impl CtrlTask for CtrlKbdLedZbus {
impl crate::Reloadable for CtrlKbdLedZbus {
async fn reload(&mut self) -> Result<(), RogError> {
let mut ctrl = self.0.lock().await;
debug!("CtrlKbdLedZbus: reloading keyboard mode");
ctrl.write_current_config_mode()?;
debug!("CtrlKbdLedZbus: reloading power states");
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
Ok(())
}

View File

@@ -31,12 +31,14 @@ impl GetSupported for CtrlPlatform {
fn get_supported() -> Self::A {
let mut panel_overdrive = false;
let mut mini_led_mode = false;
let mut dgpu_disable = false;
let mut egpu_enable = false;
let mut gpu_mux = false;
if let Ok(platform) = AsusPlatform::new() {
panel_overdrive = platform.has_panel_od();
mini_led_mode = platform.has_mini_led_mode();
dgpu_disable = platform.has_dgpu_disable();
egpu_enable = platform.has_egpu_enable();
gpu_mux = platform.has_gpu_mux_mode();
@@ -46,6 +48,7 @@ impl GetSupported for CtrlPlatform {
post_sound: Path::new(ASUS_POST_LOGO_SOUND).exists(),
gpu_mux,
panel_overdrive,
mini_led_mode,
dgpu_disable,
egpu_enable,
}
@@ -179,7 +182,13 @@ impl CtrlPlatform {
err
})
.ok();
Self::notify_post_boot_sound(&ctxt, on).await.ok();
Self::notify_post_boot_sound(&ctxt, on)
.await
.map_err(|err| {
warn!("CtrlRogBios: set_post_boot_sound {}", err);
err
})
.ok();
}
fn post_boot_sound(&self) -> i8 {
@@ -194,18 +203,13 @@ impl CtrlPlatform {
#[dbus_interface(signal)]
async fn notify_post_boot_sound(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {}
async fn set_panel_od(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
overdrive: bool,
) {
async fn set_panel_od(&mut self, overdrive: bool) {
match self.platform.set_panel_od(overdrive) {
Ok(_) => {
if let Some(mut lock) = self.config.try_lock() {
lock.panel_od = overdrive;
lock.write();
}
Self::notify_panel_od(&ctxt, overdrive).await.ok();
}
Err(err) => warn!("CtrlRogBios: set_panel_overdrive {}", err),
};
@@ -214,25 +218,46 @@ impl CtrlPlatform {
/// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also.
fn panel_od(&self) -> bool {
let od = self
.platform
self.platform
.get_panel_od()
.map_err(|err| {
warn!("CtrlRogBios: get_panel_od {}", err);
err
})
.unwrap_or(false);
if let Some(mut lock) = self.config.try_lock() {
lock.panel_od = od;
lock.write();
}
od
.unwrap_or(false)
}
#[dbus_interface(signal)]
async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> {
}
async fn set_mini_led_mode(&mut self, on: bool) {
match self.platform.set_mini_led_mode(on) {
Ok(_) => {
if let Some(mut lock) = self.config.try_lock() {
lock.mini_led_mode = on;
lock.write();
}
}
Err(err) => warn!("CtrlRogBios: set_mini_led_mode {}", err),
};
}
/// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also.
fn mini_led_mode(&self) -> bool {
self.platform
.get_mini_led_mode()
.map_err(|err| {
warn!("CtrlRogBios: get_mini_led_mode {}", err);
err
})
.unwrap_or(false)
}
#[dbus_interface(signal)]
async fn notify_mini_led_mode(signal_ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {}
async fn set_dgpu_disable(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
@@ -319,6 +344,8 @@ impl CtrlPlatform {
task_watch_item!(dgpu_disable platform);
task_watch_item!(egpu_enable platform);
task_watch_item!(mini_led_mode platform);
// NOTE: see note further below
// task_watch_item!(gpu_mux_mode platform);
}
@@ -343,7 +370,7 @@ impl CtrlTask for CtrlPlatform {
platform1
.set_panel_overdrive(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
warn!("CtrlCharge: panel_od {}", err);
err
})
.ok();
@@ -360,7 +387,7 @@ impl CtrlTask for CtrlPlatform {
platform2
.set_panel_overdrive(lock.panel_od)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
warn!("CtrlCharge: panel_od {}", err);
err
})
.ok();
@@ -373,6 +400,7 @@ impl CtrlTask for CtrlPlatform {
self.watch_panel_od(signal_ctxt.clone()).await?;
self.watch_dgpu_disable(signal_ctxt.clone()).await?;
self.watch_egpu_enable(signal_ctxt.clone()).await?;
self.watch_mini_led_mode(signal_ctxt.clone()).await?;
// NOTE: Can't have this as a watch because on a write to it, it reverts back to
// booted-with value as it does not actually change until reboot.
// self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;

View File

@@ -14,7 +14,7 @@ use zbus::{dbus_interface, Connection, SignalContext};
use crate::config::Config;
use crate::error::RogError;
use crate::{task_watch_item, CtrlTask, GetSupported};
use crate::{CtrlTask, GetSupported};
const ZBUS_PATH: &str = "/org/asuslinux/Power";
const NVIDIA_POWERD: &str = "nvidia-powerd.service";
@@ -120,7 +120,7 @@ impl crate::Reloadable for CtrlPower {
}
impl CtrlPower {
task_watch_item!(charge_control_end_threshold power);
// task_watch_item!(charge_control_end_threshold power);
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
Ok(CtrlPower {
@@ -211,8 +211,8 @@ impl CtrlTask for CtrlPower {
.await;
let config = self.config.clone();
self.watch_charge_control_end_threshold(signal_ctxt.clone())
.await?;
// self.watch_charge_control_end_threshold(signal_ctxt.clone())
// .await?;
let ctrl = self.clone();
tokio::spawn(async move {

View File

@@ -1,7 +1,7 @@
use std::path::PathBuf;
use config_traits::{StdConfig, StdConfigLoad};
use rog_profiles::fan_curve_set::FanCurveSet;
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::Profile;
use serde_derive::{Deserialize, Serialize};
@@ -36,9 +36,9 @@ impl StdConfigLoad for ProfileConfig {}
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct FanCurveConfig {
pub balanced: FanCurveSet,
pub performance: FanCurveSet,
pub quiet: FanCurveSet,
pub balanced: Vec<CurveData>,
pub performance: Vec<CurveData>,
pub quiet: Vec<CurveData>,
}
impl StdConfig for FanCurveConfig {
@@ -48,13 +48,13 @@ impl StdConfig for FanCurveConfig {
Self::default()
}
fn config_dir() -> std::path::PathBuf {
PathBuf::from(CONFIG_PATH_BASE)
}
fn file_name(&self) -> String {
CONFIG_FAN_FILE.to_owned()
}
fn config_dir() -> std::path::PathBuf {
PathBuf::from(CONFIG_PATH_BASE)
}
}
impl StdConfigLoad for FanCurveConfig {}

View File

@@ -56,13 +56,9 @@ impl GetSupported for CtrlPlatformProfile {
);
}
let res = FanCurveProfiles::is_supported();
let mut fan_curve_supported = res.is_err();
if let Ok(r) = res {
fan_curve_supported = r;
};
let res = FanCurveProfiles::supported_fans();
if !fan_curve_supported {
if res.is_err() {
info!(
"fan curves kernel interface not found, your laptop does not support this, or the \
interface is missing."
@@ -71,7 +67,7 @@ impl GetSupported for CtrlPlatformProfile {
PlatformProfileFunctions {
platform_profile: Profile::is_platform_profile_supported(),
fan_curves: fan_curve_supported,
fans: res.unwrap_or_default(),
}
}
}
@@ -101,16 +97,22 @@ impl CtrlPlatformProfile {
// For each profile we need to switch to it before we
// can read the existing values from hardware. The ACPI method used
// for this is what limits us.
controller.set_next_profile()?;
let next =
Profile::get_next_profile(controller.profile_config.active_profile);
Profile::set_profile(next)
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
.ok();
controller.profile_config.active_profile = next;
// Make sure to set the baseline to default
controller.set_active_curve_to_defaults()?;
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
if let Some(curves) = controller.fan_curves.as_ref() {
info!(
"{MOD_NAME}: {active:?}: {}",
String::from(curves.profiles().get_fan_curves_for(active))
);
info!("{MOD_NAME}: {active:?}:");
for curve in curves.profiles().get_fan_curves_for(active) {
info!("{}", String::from(curve));
}
}
}
if let Some(curves) = controller.fan_curves.as_ref() {
@@ -141,28 +143,6 @@ impl CtrlPlatformProfile {
}
}
/// Toggle to next profile in list. This will first read the config, switch,
/// then write out
pub(super) fn set_next_profile(&mut self) -> Result<(), RogError> {
// Read first just incase the user has modified the config before calling this
match self.profile_config.active_profile {
Profile::Balanced => {
Profile::set_profile(Profile::Performance)?;
self.profile_config.active_profile = Profile::Performance;
}
Profile::Performance => {
Profile::set_profile(Profile::Quiet)?;
self.profile_config.active_profile = Profile::Quiet;
}
Profile::Quiet => {
Profile::set_profile(Profile::Balanced)?;
self.profile_config.active_profile = Profile::Balanced;
}
}
self.write_profile_curve_to_platform()?;
Ok(())
}
/// Set the curve for the active profile active
pub(super) fn write_profile_curve_to_platform(&mut self) -> Result<(), RogError> {
if let Some(curves) = &mut self.fan_curves {

View File

@@ -4,8 +4,8 @@ use std::sync::Arc;
use async_trait::async_trait;
use config_traits::StdConfig;
use log::{error, info, warn};
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
use rog_profiles::{FanCurveProfiles, Profile};
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::{FanCurvePU, FanCurveProfiles, Profile};
use zbus::export::futures_util::lock::Mutex;
use zbus::export::futures_util::StreamExt;
use zbus::fdo::Error;
@@ -40,8 +40,11 @@ impl ProfileZbus {
/// If fan-curves are supported will also activate a fan curve for profile.
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
let mut ctrl = self.0.lock().await;
ctrl.set_next_profile()
.unwrap_or_else(|err| warn!("{MOD_NAME}: {}", err));
let next = Profile::get_next_profile(ctrl.profile_config.active_profile);
Profile::set_profile(next)
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
.ok();
ctrl.profile_config.active_profile = next;
ctrl.save_config();
Self::notify_profile(&ctxt, ctrl.profile_config.active_profile)
@@ -80,19 +83,9 @@ impl ProfileZbus {
.ok();
}
/// Get a list of profiles that have fan-curves enabled.
async fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
let mut ctrl = self.0.lock().await;
ctrl.profile_config.read();
if let Some(curves) = &mut ctrl.fan_curves {
return Ok(curves.profiles().get_enabled_curve_profiles());
}
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
}
/// Set a profile fan curve enabled status. Will also activate a fan curve
/// if in the same profile mode
async fn set_fan_curve_enabled(
/// Set all fan curves for a profile to enabled status. Will also activate a
/// fan curve if in the same profile mode
async fn set_fan_curves_enabled(
&mut self,
profile: Profile,
enabled: bool,
@@ -102,7 +95,33 @@ impl ProfileZbus {
if let Some(curves) = &mut ctrl.fan_curves {
curves
.profiles_mut()
.set_profile_curve_enabled(profile, enabled);
.set_profile_curves_enabled(profile, enabled);
ctrl.write_profile_curve_to_platform()
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
.ok();
ctrl.save_config();
Ok(())
} else {
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
}
}
/// Set a single fan curve for a profile to enabled status. Will also
/// activate a fan curve if in the same profile mode
async fn set_profile_fan_curve_enabled(
&mut self,
profile: Profile,
fan: FanCurvePU,
enabled: bool,
) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.profile_config.read();
if let Some(curves) = &mut ctrl.fan_curves {
curves
.profiles_mut()
.set_profile_fan_curve_enabled(profile, fan, enabled);
ctrl.write_profile_curve_to_platform()
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
@@ -116,12 +135,12 @@ impl ProfileZbus {
}
/// Get the fan-curve data for the currently active Profile
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<Vec<CurveData>> {
let mut ctrl = self.0.lock().await;
ctrl.profile_config.read();
if let Some(curves) = &mut ctrl.fan_curves {
let curve = curves.profiles().get_fan_curves_for(profile);
return Ok(curve.clone());
return Ok(curve.to_vec());
}
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
}
@@ -207,7 +226,7 @@ impl CtrlTask for ProfileZbus {
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
let ctrl = self.0.clone();
let sig_ctx = signal_ctxt.clone();
let mut watch = self
let watch = self
.0
.lock()
.await
@@ -216,7 +235,7 @@ impl CtrlTask for ProfileZbus {
tokio::spawn(async move {
let mut buffer = [0; 32];
if let Ok(stream) = watch.event_stream(&mut buffer) {
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
stream
.for_each(|_| async {
let mut lock = ctrl.lock().await;
@@ -236,10 +255,11 @@ impl CtrlTask for ProfileZbus {
error!("Profile::set_profile() error: {e}");
})
.ok();
Self::notify_profile(&sig_ctx, lock.profile_config.active_profile)
.await
.ok();
}
Self::notify_profile(&sig_ctx, lock.profile_config.active_profile)
.await
.ok();
}
})
.await;
@@ -247,11 +267,11 @@ impl CtrlTask for ProfileZbus {
});
let ctrl = self.0.clone();
let mut watch = self.0.lock().await.platform.monitor_platform_profile()?;
let watch = self.0.lock().await.platform.monitor_platform_profile()?;
tokio::spawn(async move {
let mut buffer = [0; 32];
if let Ok(stream) = watch.event_stream(&mut buffer) {
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
stream
.for_each(|_| async {
let mut lock = ctrl.lock().await;
@@ -271,13 +291,14 @@ impl CtrlTask for ProfileZbus {
error!("Profile::set_profile() error: {e}");
})
.ok();
Self::notify_profile(
&signal_ctxt,
lock.profile_config.active_profile,
)
.await
.ok();
}
Self::notify_profile(
&signal_ctxt,
lock.profile_config.active_profile,
)
.await
.ok();
}
}
})

View File

@@ -15,8 +15,15 @@ pub struct SupportedFunctions(rog_platform::supported::SupportedFunctions);
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl SupportedFunctions {
pub fn supported_functions(&self) -> &rog_platform::supported::SupportedFunctions {
&self.0
pub fn supported_functions(
&self,
) -> zbus::fdo::Result<&rog_platform::supported::SupportedFunctions> {
Ok(&self.0)
}
#[dbus_interface(out_args("answer", "question"))]
fn meaning_of_life(&self) -> zbus::fdo::Result<(i32, String)> {
Ok((42, String::from("Meaning of life")))
}
}

View File

@@ -6,20 +6,20 @@ use std::time::Duration;
use ::zbus::export::futures_util::lock::Mutex;
use ::zbus::Connection;
use asusd::config::Config;
use asusd::ctrl_anime::config::AnimeConfig;
use asusd::ctrl_anime::trait_impls::CtrlAnimeZbus;
use asusd::ctrl_anime::CtrlAnime;
use asusd::ctrl_aura::controller::CtrlKbdLed;
use asusd::ctrl_aura::trait_impls::CtrlKbdLedZbus;
use asusd::ctrl_platform::CtrlPlatform;
use asusd::ctrl_power::CtrlPower;
use asusd::ctrl_profiles::config::ProfileConfig;
use asusd::ctrl_profiles::controller::CtrlPlatformProfile;
use asusd::ctrl_profiles::trait_impls::ProfileZbus;
use asusd::ctrl_supported::SupportedFunctions;
use asusd::{print_board_info, CtrlTask, GetSupported, Reloadable, ZbusRun};
use config_traits::{StdConfig, StdConfigLoad, StdConfigLoad2};
use daemon::config::Config;
use daemon::ctrl_anime::config::AnimeConfig;
use daemon::ctrl_anime::trait_impls::CtrlAnimeZbus;
use daemon::ctrl_anime::CtrlAnime;
use daemon::ctrl_aura::controller::CtrlKbdLed;
use daemon::ctrl_aura::trait_impls::CtrlKbdLedZbus;
use daemon::ctrl_platform::CtrlPlatform;
use daemon::ctrl_power::CtrlPower;
use daemon::ctrl_profiles::config::ProfileConfig;
use daemon::ctrl_profiles::controller::CtrlPlatformProfile;
use daemon::ctrl_profiles::trait_impls::ProfileZbus;
use daemon::ctrl_supported::SupportedFunctions;
use daemon::{print_board_info, CtrlTask, GetSupported, Reloadable, ZbusRun};
use log::{error, info, warn};
use rog_aura::aura_detection::LaptopLedData;
use rog_dbus::DBUS_NAME;
@@ -50,7 +50,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
return Ok(());
}
info!(" daemon v{}", daemon::VERSION);
info!(" daemon v{}", asusd::VERSION);
info!(" rog-anime v{}", rog_anime::VERSION);
info!(" rog-aura v{}", rog_aura::VERSION);
info!(" rog-dbus v{}", rog_dbus::VERSION);
@@ -65,7 +65,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn start_daemon() -> Result<(), Box<dyn Error>> {
let supported = SupportedFunctions::get_supported();
print_board_info();
println!("{}", supported.supported_functions());
println!("{:?}", supported.supported_functions());
// Start zbus server
let mut connection = Connection::system().await?;

View File

@@ -51,6 +51,7 @@ const CONFIG_PATH_BASE: &str = "/etc/asusd/";
/// task_watch_item!(gpu_mux_mode platform);
/// }
/// ```
/// // TODO: this is kind of useless if it can't trigger some action
#[macro_export]
macro_rules! task_watch_item {
($name:ident $self_inner:ident) => {
@@ -64,10 +65,10 @@ macro_rules! task_watch_item {
let ctrl = self.clone();
concat_idents::concat_idents!(watch_fn = monitor_, $name {
match self.$self_inner.watch_fn() {
Ok(mut watch) => {
Ok(watch) => {
tokio::spawn(async move {
let mut buffer = [0; 32];
watch.event_stream(&mut buffer).unwrap().for_each(|_| async {
watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async {
let value = ctrl.$name();
concat_idents::concat_idents!(notif_fn = notify_, $name {
Self::notif_fn(&signal_ctxt, value).await.ok();

View File

@@ -0,0 +1,65 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<!--
Writes a data stream of length. Will force system thread to exit until
it is restarted
-->
<method name="Write">
<arg name="input" type="(ays)" direction="in"/>
</method>
<!--
Set the global AniMe brightness
-->
<method name="SetImageBrightness">
<arg name="bright" type="d" direction="in"/>
</method>
<!--
Set base brightness level
-->
<method name="SetBrightness">
<arg name="brightness" type="s" direction="in"/>
</method>
<!--
Enable the builtin animations or not
-->
<method name="SetBuiltinsEnabled">
<arg name="enabled" type="b" direction="in"/>
</method>
<!--
Set which builtin animation is used for each stage
-->
<method name="SetBuiltinAnimations">
<arg name="boot" type="s" direction="in"/>
<arg name="awake" type="s" direction="in"/>
<arg name="sleep" type="s" direction="in"/>
<arg name="shutdown" type="s" direction="in"/>
</method>
<!--
Set whether the AniMe is enabled at all
-->
<method name="SetEnableDisplay">
<arg name="enabled" type="b" direction="in"/>
</method>
<!--
The main loop is the base system set action if the user isn't running
the user daemon
-->
<method name="RunMainLoop">
<arg name="start" type="b" direction="in"/>
</method>
<!--
Get the device state as stored by asusd
-->
<method name="DeviceState">
<arg type="bsb(ssss)" direction="out"/>
</method>
<!--
Notify listeners of the status of AniMe LED power and factory
system-status animations
-->
<signal name="NotifyDeviceState">
<arg name="data" type="(bsb(ssss))"/>
</signal>
</interface>
</node>

View File

@@ -0,0 +1,71 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<!--
Set the keyboard brightness level (0-3)
-->
<method name="SetBrightness">
<arg name="brightness" type="s" direction="in"/>
</method>
<!--
Set a variety of states, input is array of enum.
`enabled` sets if the sent array should be disabled or enabled
For Modern ROG devices the "enabled" flag is ignored.
-->
<method name="SetLedPower">
<arg name="options" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))" direction="in"/>
<arg name="enabled" type="b" direction="in"/>
</method>
<method name="SetLedMode">
<arg name="effect" type="(ss(yyy)(yyy)ss)" direction="in"/>
</method>
<method name="NextLedMode">
</method>
<method name="PrevLedMode">
</method>
<method name="NextLedBrightness">
</method>
<method name="PrevLedBrightness">
</method>
<!--
Return the device type for this Aura keyboard
-->
<method name="DeviceType">
<arg type="s" direction="out"/>
</method>
<method name="LedPower">
<arg type="asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb))" direction="out"/>
</method>
<!--
Return the current mode data
-->
<method name="LedMode">
<arg type="s" direction="out"/>
</method>
<!--
Return a list of available modes
-->
<method name="LedModes">
<arg type="a{s(ss(yyy)(yyy)ss)}" direction="out"/>
</method>
<!--
On machine that have some form of either per-key keyboard or per-zone
this can be used to write custom effects over dbus. The input is a
nested `Vec<Vec<8>>` where `Vec<u8>` is a raw USB packet
-->
<method name="DirectAddressingRaw">
<arg name="data" type="aay" direction="in"/>
</method>
<signal name="NotifyLed">
<arg name="data" type="(ss(yyy)(yyy)ss)"/>
</signal>
<signal name="NotifyPowerStates">
<arg name="data" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))"/>
</signal>
<!--
Return the current LED brightness
-->
<property name="LedBrightness" type="n" access="read"/>
</interface>
</node>

View File

@@ -0,0 +1,67 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<method name="SetGpuMuxMode">
<arg name="mode" type="u" direction="in"/>
</method>
<method name="GpuMuxMode">
<arg type="u" direction="out"/>
</method>
<signal name="NotifyGpuMuxMode">
<arg name="mode" type="u"/>
</signal>
<method name="SetPostBootSound">
<arg name="on" type="b" direction="in"/>
</method>
<method name="PostBootSound">
<arg type="n" direction="out"/>
</method>
<signal name="NotifyPostBootSound">
<arg name="on" type="b"/>
</signal>
<method name="SetPanelOd">
<arg name="overdrive" type="b" direction="in"/>
</method>
<!--
Get the `panel_od` value from platform. Updates the stored value in
internal config also.
-->
<method name="PanelOd">
<arg type="b" direction="out"/>
</method>
<signal name="NotifyPanelOd">
<arg name="overdrive" type="b"/>
</signal>
<method name="SetMiniLedMode">
<arg name="on" type="b" direction="in"/>
</method>
<!--
Get the `panel_od` value from platform. Updates the stored value in
internal config also.
-->
<method name="MiniLedMode">
<arg type="b" direction="out"/>
</method>
<signal name="NotifyMiniLedMode">
<arg name="on" type="b"/>
</signal>
<method name="SetDgpuDisable">
<arg name="disable" type="b" direction="in"/>
</method>
<method name="DgpuDisable">
<arg type="b" direction="out"/>
</method>
<signal name="NotifyDgpuDisable">
<arg name="disable" type="b"/>
</signal>
<method name="SetEgpuEnable">
<arg name="enable" type="b" direction="in"/>
</method>
<method name="EgpuEnable">
<arg type="b" direction="out"/>
</method>
<signal name="NotifyEgpuEnable">
<arg name="enable" type="b"/>
</signal>
</interface>
</node>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<method name="SetChargeControlEndThreshold">
<arg name="limit" type="y" direction="in"/>
</method>
<method name="ChargeControlEndThreshold">
<arg type="y" direction="out"/>
</method>
<method name="MainsOnline">
<arg type="b" direction="out"/>
</method>
<signal name="NotifyChargeControlEndThreshold">
<arg name="limit" type="y"/>
</signal>
<signal name="NotifyMainsOnline">
<arg name="on" type="b"/>
</signal>
</interface>
</node>

View File

@@ -0,0 +1,80 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<!--
Fetch profile names
-->
<method name="Profiles">
<arg type="as" direction="out"/>
</method>
<!--
Toggle to next platform_profile. Names provided by `Profiles`.
If fan-curves are supported will also activate a fan curve for profile.
-->
<method name="NextProfile">
</method>
<!--
Fetch the active profile name
-->
<method name="ActiveProfile">
<arg type="s" direction="out"/>
</method>
<!--
Set this platform_profile name as active
-->
<method name="SetActiveProfile">
<arg name="profile" type="s" direction="in"/>
</method>
<!--
Get a list of profiles that have fan-curves enabled.
-->
<method name="EnabledFanProfiles">
<arg type="as" direction="out"/>
</method>
<!--
Set a profile fan curve enabled status. Will also activate a fan curve
if in the same profile mode
-->
<method name="SetFanCurveEnabled">
<arg name="profile" type="s" direction="in"/>
<arg name="enabled" type="b" direction="in"/>
</method>
<!--
Get the fan-curve data for the currently active Profile
-->
<method name="FanCurveData">
<arg name="profile" type="s" direction="in"/>
<arg type="(b(s(yyyyyyyy)(yyyyyyyy))(s(yyyyyyyy)(yyyyyyyy)))" direction="out"/>
</method>
<!--
Set the fan curve for the specified profile.
Will also activate the fan curve if the user is in the same mode.
-->
<method name="SetFanCurve">
<arg name="profile" type="s" direction="in"/>
<arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy))" direction="in"/>
</method>
<!--
Reset the stored (self) and device curve to the defaults of the
platform.
Each platform_profile has a different default and the defualt can be
read only for the currently active profile.
-->
<method name="SetActiveCurveToDefaults">
</method>
<!--
Reset the stored (self) and device curve to the defaults of the
platform.
Each platform_profile has a different default and the defualt can be
read only for the currently active profile.
-->
<method name="ResetProfileCurves">
<arg name="profile" type="s" direction="in"/>
</method>
<signal name="NotifyProfile">
<arg name="profile" type="s"/>
</signal>
</interface>
</node>

View File

@@ -0,0 +1,12 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.asuslinux.Daemon">
<method name="SupportedFunctions">
<arg type="b(b)(bb)(sbasassas)(bbbbbb)" direction="out"/>
</method>
<method name="MeaningOfLife">
<arg name="answer" type="i" direction="out"/>
<arg name="question" type="s" direction="out"/>
</method>
</interface>
</node>

53
bindings/ts/anime.ts Normal file
View File

@@ -0,0 +1,53 @@
/*
Generated by typeshare 1.6.0
*/
export enum AnimBooting {
GlitchConstruction = "GlitchConstruction",
StaticEmergence = "StaticEmergence",
}
export enum AnimAwake {
BinaryBannerScroll = "BinaryBannerScroll",
RogLogoGlitch = "RogLogoGlitch",
}
export enum AnimSleeping {
BannerSwipe = "BannerSwipe",
Starfield = "Starfield",
}
export enum AnimShutdown {
GlitchOut = "GlitchOut",
SeeYa = "SeeYa",
}
export interface Animations {
boot: AnimBooting;
awake: AnimAwake;
sleep: AnimSleeping;
shutdown: AnimShutdown;
}
/** Base LED brightness of the display */
export enum Brightness {
Off = "Off",
Low = "Low",
Med = "Med",
High = "High",
}
export interface DeviceState {
display_enabled: boolean;
display_brightness: Brightness;
builtin_anims_enabled: boolean;
builtin_anims: Animations;
}
export enum AnimeType {
GA401 = "GA401",
GA402 = "GA402",
GU604 = "GU604",
Unknown = "Unknown",
}

232
bindings/ts/aura.ts Normal file
View File

@@ -0,0 +1,232 @@
/*
Generated by typeshare 1.6.0
*/
/** Represents the per-key raw USB packets */
export type UsbPackets = number[][];
/**
* A `UsbPackets` contains all data to change the full set of keyboard
* key colours individually.
*
* Each row of the internal array is a full HID packet that can be sent
* to the keyboard EC. One row controls one group of keys, these keys are not
* necessarily all on the same row of the keyboard, with some splitting between
* two rows.
*/
export interface LedUsbPackets {
/** The packet data used to send data to the USB keyboard */
usb_packets: UsbPackets;
/**
* Wether or not this packet collection is zoned. The determines which
* starting bytes are used and what the indexing is for lightbar RGB
* colours
*/
zoned: boolean;
}
export interface Colour {
r: number;
g: number;
b: number;
}
/** Enum of modes that convert to the actual number required by a USB HID packet */
export enum AuraModeNum {
Static = "Static",
Breathe = "Breathe",
Strobe = "Strobe",
Rainbow = "Rainbow",
Star = "Star",
Rain = "Rain",
Highlight = "Highlight",
Laser = "Laser",
Ripple = "Ripple",
Pulse = "Pulse",
Comet = "Comet",
Flash = "Flash",
}
/** Base effects have no zoning, while multizone is 1-4 */
export enum AuraZone {
/** Used if keyboard has no zones, or if setting all */
None = "None",
/** Leftmost zone */
Key1 = "Key1",
/** Zone after leftmost */
Key2 = "Key2",
/** Zone second from right */
Key3 = "Key3",
/** Rightmost zone */
Key4 = "Key4",
/** Logo on the lid (or elsewhere?) */
Logo = "Logo",
/** The left part of a lightbar (typically on the front of laptop) */
BarLeft = "BarLeft",
/** The right part of a lightbar */
BarRight = "BarRight",
}
export enum Speed {
Low = "Low",
Med = "Med",
High = "High",
}
/**
* Used for Rainbow mode.
*
* Enum corresponds to the required integer value
*/
export enum Direction {
Right = "Right",
Left = "Left",
Up = "Up",
Down = "Down",
}
/**
* Default factory modes structure. This easily converts to an USB HID packet
* with:
* ```rust
* // let bytes: [u8; LED_MSG_LEN] = mode.into();
* ```
*/
export interface AuraEffect {
/** The effect type */
mode: AuraModeNum;
/** `AuraZone::None` for no zone or zoneless keyboards */
zone: AuraZone;
/** Primary colour for all modes */
colour1: Colour;
/** Secondary colour in some modes like Breathing or Stars */
colour2: Colour;
/** One of three speeds for modes that support speed (most that animate) */
speed: Speed;
/** Up, down, left, right. Only Rainbow mode seems to use this */
direction: Direction;
}
/** The powerr zones this laptop supports */
export enum PowerZones {
/** The logo on some laptop lids */
Logo = "Logo",
/** The full keyboard (not zones) */
Keyboard = "Keyboard",
/** The lightbar, typically on the front of the laptop */
Lightbar = "Lightbar",
/** The leds that may be placed around the edge of the laptop lid */
Lid = "Lid",
/** The led strip on the rear of some laptops */
RearGlow = "RearGlow",
}
export interface KbAuraPowerState {
zone: PowerZones;
boot: boolean;
awake: boolean;
sleep: boolean;
shutdown: boolean;
}
/**
* Track and control the Aura keyboard power state
*
* # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
*
* | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
* |--------|---------|---------|---------|----------|
* |00000001| 00000000| 00000000| 00000000|boot_logo_|
* |00000010| 00000000| 00000000| 00000000|boot_keyb_|
* |00000100| 00000000| 00000000| 00000000|awake_logo|
* |00001000| 00000000| 00000000| 00000000|awake_keyb|
* |00010000| 00000000| 00000000| 00000000|sleep_logo|
* |00100000| 00000000| 00000000| 00000000|sleep_keyb|
* |01000000| 00000000| 00000000| 00000000|shut_logo_|
* |10000000| 00000000| 00000000| 00000000|shut_keyb_|
* |00000000| 00000010| 00000000| 00000000|boot_bar__|
* |00000000| 00000100| 00000000| 00000000|awake_bar_|
* |00000000| 00001000| 00000000| 00000000|sleep_bar_|
* |00000000| 00010000| 00000000| 00000000|shut_bar__|
* |00000000| 00000000| 00000001| 00000000|boot_lid__|
* |00000000| 00000000| 00000010| 00000000|awkae_lid_|
* |00000000| 00000000| 00000100| 00000000|sleep_lid_|
* |00000000| 00000000| 00001000| 00000000|shut_lid__|
* |00000000| 00000000| 00000000| 00000001|boot_rear_|
* |00000000| 00000000| 00000000| 00000010|awake_rear|
* |00000000| 00000000| 00000000| 00000100|sleep_rear|
* |00000000| 00000000| 00000000| 00001000|shut_rear_|
*/
export interface AuraPower {
keyboard: KbAuraPowerState;
logo: KbAuraPowerState;
lightbar: KbAuraPowerState;
lid: KbAuraPowerState;
rear_glow: KbAuraPowerState;
}
export enum AuraDevTuf {
Boot = "Boot",
Awake = "Awake",
Sleep = "Sleep",
Keyboard = "Keyboard",
}
/**
* # Bits for older 0x1866 keyboard model
*
* Keybord and Lightbar require Awake, Boot and Sleep apply to both
* Keybord and Lightbar regardless of if either are enabled (or Awake is
* enabled)
*
* | Byte 1 | Byte 2 | Byte 3 | function | hex |
* |------------|------------|------------|----------|----------|
* | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
* | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
* | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
* | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
* | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
* | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
*/
export enum AuraDevRog1 {
Awake = "Awake",
Keyboard = "Keyboard",
Lightbar = "Lightbar",
Boot = "Boot",
Sleep = "Sleep",
}
/** This struct is intended as a helper to pass args to generic dbus interface */
export interface AuraPowerDev {
/**
* TUF laptops use a similar style of control to the older ROG devices but
* through WMI
*/
tuf: AuraDevTuf[];
/**
* Pre-0x19b6 devices use a different smaller scheme to the newer ROG
* devices
*/
old_rog: AuraDevRog1[];
/** ASUS standardised control scheme from 2020 onwards */
rog: AuraPower;
}
export enum LedBrightness {
Off = "Off",
Low = "Low",
Med = "Med",
High = "High",
}
export enum AuraDevice {
Tuf = "Tuf",
X1854 = "X1854",
X1869 = "X1869",
X1866 = "X1866",
X18c6 = "X18c6",
X19b6 = "X19b6",
X1a30 = "X1a30",
Unknown = "Unknown",
}

58
bindings/ts/platform.ts Normal file
View File

@@ -0,0 +1,58 @@
/*
Generated by typeshare 1.6.0
*/
export type AnimeSupportedFunctions = boolean;
export interface ChargeSupportedFunctions {
charge_level_set: boolean;
}
export interface PlatformProfileFunctions {
platform_profile: boolean;
fan_curves: boolean;
}
export enum AdvancedAura {
None = "None",
Zoned = "Zoned",
PerKey = "PerKey",
}
export interface LedSupportedFunctions {
dev_id: AuraDevice;
brightness: boolean;
basic_modes: AuraModeNum[];
basic_zones: AuraZone[];
advanced_type: AdvancedAura;
power_zones: PowerZones[];
}
export interface RogBiosSupportedFunctions {
post_sound: boolean;
gpu_mux: boolean;
panel_overdrive: boolean;
dgpu_disable: boolean;
egpu_enable: boolean;
mini_led_mode: boolean;
}
export interface SupportedFunctions {
anime_ctrl: AnimeSupportedFunctions;
charge_ctrl: ChargeSupportedFunctions;
platform_profile: PlatformProfileFunctions;
keyboard_led: LedSupportedFunctions;
rog_bios_ctrl: RogBiosSupportedFunctions;
}
export enum GpuMode {
Discrete = "Discrete",
Optimus = "Optimus",
Integrated = "Integrated",
Egpu = "Egpu",
Vfio = "Vfio",
Ultimate = "Ultimate",
Error = "Error",
NotSupported = "NotSupported",
}

35
bindings/ts/profiles.ts Normal file
View File

@@ -0,0 +1,35 @@
/*
Generated by typeshare 1.6.0
*/
export enum FanCurvePU {
CPU = "CPU",
GPU = "GPU",
}
export interface CurveData {
fan: FanCurvePU;
pwm: [number, number, number, number, number, number, number, number];
temp: [number, number, number, number, number, number, number, number];
}
/** A `FanCurveSet` contains both CPU and GPU fan curve data */
export interface FanCurveSet {
enabled: boolean;
cpu: CurveData;
gpu: CurveData;
}
/** Main purpose of `FanCurves` is to enable restoring state on system boot */
export interface FanCurveProfiles {
balanced: FanCurveSet;
performance: FanCurveSet;
quiet: FanCurveSet;
}
export enum Profile {
Balanced = "Balanced",
Performance = "Performance",
Quiet = "Quiet",
}

View File

@@ -1,212 +0,0 @@
use std::sync::atomic::Ordering;
use std::sync::Arc;
use async_trait::async_trait;
use config_traits::StdConfig;
use log::warn;
use rog_anime::usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on};
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
use zbus::export::futures_util::lock::Mutex;
use zbus::{dbus_interface, Connection, SignalContext};
use super::CtrlAnime;
use crate::error::RogError;
pub(super) const ZBUS_PATH: &str = "/org/asuslinux/Anime";
#[derive(Clone)]
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
/// The struct with the main dbus methods requires this trait
#[async_trait]
impl crate::ZbusRun for CtrlAnimeZbus {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
}
}
// None of these calls can be guarnateed to succeed unless we loop until okay
// If the try_lock *does* succeed then any other thread trying to lock will not
// grab it until we finish.
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlAnimeZbus {
/// Writes a data stream of length. Will force system thread to exit until
/// it is restarted
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
lock.write_data_buffer(input).map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
err
})?;
Ok(())
}
/// Set the global AniMe brightness
async fn set_brightness(&self, bright: f32) {
let mut lock = self.0.lock().await;
let mut bright = bright;
if bright < 0.0 {
bright = 0.0;
} else if bright > 1.0 {
bright = 1.0;
}
lock.config.brightness = bright;
lock.config.write();
}
/// Set whether the AniMe is displaying images/data
async fn set_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, status: bool) {
let mut lock = self.0.lock().await;
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();
Self::notify_power_states(
&ctxt,
AnimePowerStates {
brightness: lock.config.brightness.floor() as u8,
enabled: lock.config.awake_enabled,
boot_anim_enabled: lock.config.boot_anim_enabled,
},
)
.await
.ok();
}
/// Set whether the AniMe will show boot, suspend, or off animations
async fn set_boot_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, on: bool) {
let mut lock = self.0.lock().await;
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();
Self::notify_power_states(
&ctxt,
AnimePowerStates {
brightness: lock.config.brightness.floor() as u8,
enabled: lock.config.awake_enabled,
boot_anim_enabled: lock.config.boot_anim_enabled,
},
)
.await
.ok();
}
/// The main loop is the base system set action if the user isn't running
/// the user daemon
async fn run_main_loop(&self, start: bool) {
if start {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false);
}
}
/// Get status of if the AniMe LEDs are on/displaying while system is awake
#[dbus_interface(property)]
async fn awake_enabled(&self) -> bool {
let lock = self.0.lock().await;
lock.config.awake_enabled
}
/// Get the status of if factory system-status animations are enabled
#[dbus_interface(property)]
async fn boot_enabled(&self) -> bool {
let lock = self.0.lock().await;
lock.config.boot_anim_enabled
}
/// Notify listeners of the status of AniMe LED power and factory
/// system-status animations
#[dbus_interface(signal)]
async fn notify_power_states(
ctxt: &SignalContext<'_>,
data: AnimePowerStates,
) -> zbus::Result<()>;
}
#[async_trait]
impl crate::CtrlTask for CtrlAnimeZbus {
fn zbus_path() -> &'static str {
ZBUS_PATH
}
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
let inner1 = self.0.clone();
let inner2 = self.0.clone();
let inner3 = self.0.clone();
let inner4 = self.0.clone();
self.create_sys_event_tasks(
move || {
// on_sleep
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true);
}
},
move || {
// on_wake
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true);
}
},
move || {
// on_shutdown
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true);
}
},
move || {
// on_boot
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true);
}
},
)
.await;
Ok(())
}
}
#[async_trait]
impl crate::Reloadable for CtrlAnimeZbus {
async fn reload(&mut self) -> Result<(), RogError> {
if let Some(lock) = self.0.try_lock() {
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);
}
Ok(())
}
}

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="0 0 512 512" width="512pt" height="512pt"><defs><clipPath id="_clipPath_8C5izdJ0sH9w7nD5UuBTlpktuZWEWJn8"><rect width="512" height="512"/></clipPath></defs><g clip-path="url(#_clipPath_8C5izdJ0sH9w7nD5UuBTlpktuZWEWJn8)"><path d=" M 113.969 270.246 C 113.969 301.718 88.456 327.231 56.985 327.231 C 25.513 327.231 0 301.718 0 270.246 C 0 238.775 25.513 213.262 56.985 213.262 C 88.456 213.262 113.969 238.775 113.969 270.246 Z M 56.985 384.215 C 41.249 384.215 28.492 396.972 28.492 412.708 C 28.492 428.443 41.249 441.2 56.985 441.2 C 72.72 441.2 85.477 428.443 85.477 412.708 C 85.477 396.972 72.72 384.215 56.985 384.215 Z M 56.985 70.8 C 25.513 70.8 0 96.313 0 127.785 C 0 159.256 25.513 184.769 56.985 184.769 C 88.456 184.769 113.969 159.256 113.969 127.785 C 113.969 96.313 88.456 70.8 56.985 70.8 Z M 199.446 241.754 C 183.71 241.754 170.954 254.51 170.954 270.246 C 170.954 285.982 183.71 298.738 199.446 298.738 C 215.182 298.738 227.938 285.982 227.938 270.246 C 227.938 254.51 215.182 241.754 199.446 241.754 Z M 199.446 384.215 C 183.71 384.215 170.954 396.972 170.954 412.708 C 170.954 428.443 183.71 441.2 199.446 441.2 C 215.182 441.2 227.938 428.443 227.938 412.708 C 227.938 396.972 215.182 384.215 199.446 384.215 Z M 199.446 70.8 C 167.975 70.8 142.462 96.313 142.462 127.785 C 142.462 159.256 167.975 184.769 199.446 184.769 C 230.918 184.769 256.431 159.256 256.431 127.785 C 256.431 96.313 230.918 70.8 199.446 70.8 Z M 339.904 241.754 C 324.169 241.754 311.412 254.51 311.412 270.246 C 311.412 285.982 324.169 298.738 339.904 298.738 C 355.64 298.738 368.397 285.982 368.397 270.246 C 368.397 254.51 355.64 241.754 339.904 241.754 Z M 339.904 384.215 C 324.169 384.215 311.412 396.972 311.412 412.708 C 311.412 428.443 324.169 441.2 339.904 441.2 C 355.64 441.2 368.397 428.443 368.397 412.708 C 368.397 396.972 355.64 384.215 339.904 384.215 Z M 339.904 70.8 C 308.433 70.8 282.92 96.313 282.92 127.785 C 282.92 159.256 308.433 184.769 339.904 184.769 C 371.376 184.769 396.889 159.256 396.889 127.785 C 396.889 96.313 371.376 70.8 339.904 70.8 Z M 482.366 241.754 C 466.63 241.754 453.874 254.51 453.874 270.246 C 453.874 285.982 466.63 298.738 482.366 298.738 C 498.102 298.738 510.858 285.982 510.858 270.246 C 510.858 254.51 498.102 241.754 482.366 241.754 Z M 482.366 384.215 C 466.63 384.215 453.874 396.972 453.874 412.708 C 453.874 428.443 466.63 441.2 482.366 441.2 C 498.102 441.2 510.858 428.443 510.858 412.708 C 510.858 396.972 498.102 384.215 482.366 384.215 Z M 482.366 99.292 C 466.63 99.292 453.874 112.049 453.874 127.785 C 453.874 143.52 466.63 156.277 482.366 156.277 C 498.102 156.277 510.858 143.52 510.858 127.785 C 510.858 112.049 498.102 99.292 482.366 99.292 Z " fill="#F2F2F2"/></g></svg>

After

Width:  |  Height:  |  Size: 2.9 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(221,221,221)"/><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(221,221,221)"/><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(221,221,221)"/></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 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="0 0 128 128" width="128pt" height="128pt"><defs><clipPath id="_clipPath_CHRnLOITGqiXLlZjYLaUfMylStiUiIRD"><rect width="128" height="128"/></clipPath></defs><g clip-path="url(#_clipPath_CHRnLOITGqiXLlZjYLaUfMylStiUiIRD)"><path d=" M 69.096 31.645 C 68.865 31.712 68.805 31.816 68.577 32.011 C 68.393 32.168 68.238 32.28 68.059 32.434 C 67.651 32.785 67.411 33.003 67.052 33.305 C 65.269 34.805 62.85 37.142 61.102 38.778 C 58.391 41.317 55.947 43.762 53.346 46.287 C 48.441 51.049 42.882 56.766 37.972 61.357 C 33.914 65.151 30.434 68.558 26.194 72.351 C 24.574 73.801 23.553 75.121 21.346 75.197 C 17.705 75.323 12.902 72.224 10.446 70.814 C 8.299 69.583 2.598 66.23 -0.15 66.137 L 1.864 68.903 C 3.303 71.1 5.724 75.885 6.887 78.214 C 10.881 86.213 16.273 94.589 23.136 100.161 C 24.891 101.586 26.481 102.783 28.71 104.132 C 29.687 104.723 30.685 105.215 31.778 105.834 C 32.157 106.049 34.786 107.277 35.11 107.276 C 34.39 106.554 33.649 105.673 33.064 104.985 C 30.452 101.912 24.64 95.938 22.894 92.889 C 21.428 90.329 21.091 88.761 22.72 86.192 C 24.582 83.254 28.924 79.619 31.648 77.289 C 38.277 71.62 44.256 66.485 51.191 61.102 C 54.478 58.551 57.895 55.949 61.429 53.427 C 64.896 50.954 68.381 48.57 72 46.178 L 77.465 42.7 C 77.972 42.409 82.95 39.446 83.029 39.347 L 87.9 36.66 C 89.536 35.736 91.124 34.964 92.857 34.031 C 97.94 31.294 108.035 26.833 113.82 24.792 C 115.718 24.122 117.528 23.489 119.449 22.833 L 125.205 21.03 C 124.739 20.79 118.379 20.724 117.207 20.724 C 112.491 20.723 109.598 20.855 105.095 21.211 C 101.65 21.483 95.237 22.19 92.104 22.948 C 91.54 23.084 90.872 23.142 90.304 23.292 C 89.218 23.578 87.974 23.775 86.861 24.052 C 84.567 24.623 82.484 25.271 80.328 25.914 C 78.108 26.575 76.101 27.36 74.115 28.177 C 72.942 28.659 69.397 31.029 69.096 31.645 L 69.096 31.645 Z M 115.16 43.036 L 119.345 40.899 C 120.797 40.208 122.299 39.413 123.667 38.745 C 126.441 37.389 128.04 32.995 127.999 30.179 C 127.509 30.199 125.516 31.144 124.975 31.342 C 124.603 31.479 124.259 31.596 123.911 31.744 C 121.439 32.794 118.139 34.036 115.795 35.142 C 115.115 35.463 114.457 35.729 113.769 36.024 C 113.228 36.256 112.036 36.724 111.814 36.999 C 111.07 36.962 95.925 44.467 94.037 45.443 C 91.35 46.833 87.97 48.499 85.386 49.936 C 85.08 50.106 77.204 54.275 76.891 54.676 C 76.372 54.762 70.974 57.968 70.112 58.454 C 59.43 64.482 47.599 72.065 37.367 79.004 C 34.524 80.933 30.892 83.463 28.034 85.617 L 25.739 87.329 C 25.476 87.53 25.165 87.663 25.013 87.965 C 26.033 88.843 32.791 91.628 34.403 92.209 C 43.451 95.47 51.92 97.742 61.441 99.376 L 67.483 100.3 L 72.241 100.72 L 68.366 100.378 C 69.105 100.462 69.839 100.582 70.559 100.651 C 71.624 100.753 72.679 100.84 73.776 100.949 C 75.841 101.157 78.238 101.298 80.361 101.335 C 82.999 101.381 84.453 101.516 86.617 100.603 C 88.294 99.894 89.659 99.013 90.992 97.992 C 95.957 94.187 100.375 88.235 103.899 82.849 C 107.587 77.213 110.909 70.915 113.773 64.675 C 115.231 61.498 116.599 58.182 117.888 54.804 C 118.541 53.092 119.107 51.439 119.697 49.622 C 120.023 48.617 121.212 44.945 121.302 44.125 C 119.948 44.31 96.265 57.088 94.012 58.297 C 90.956 59.938 88.029 61.647 85.064 63.258 C 82.182 64.823 79.134 66.672 76.267 68.266 C 70.441 71.504 64.575 75.11 58.757 78.479 C 57.76 79.056 50.352 83.387 50.086 83.691 C 50.584 83.611 74.07 73.525 74.639 73.29 C 75.746 72.832 98.806 62.937 99.184 62.92 C 99.052 63.454 97.624 66.118 97.264 66.901 C 96.664 68.206 95.94 69.692 95.284 70.989 C 91.565 78.346 87.529 87.178 79.411 90.439 L 78.923 90.732 C 78.488 90.742 77.299 91.225 76.775 91.369 C 75.986 91.586 75.223 91.736 74.428 91.899 C 70.686 92.665 65.028 92.266 61.129 91.656 C 56.682 90.96 53.568 90.179 49.258 89.137 C 48.229 88.889 40.792 86.799 40.362 86.516 C 40.604 86.093 44.858 83.368 45.23 83.109 C 53.46 77.389 67.13 68.983 76.02 63.925 C 76.961 63.389 77.835 62.903 78.696 62.41 C 79.411 62 80.72 61.317 81.298 60.897 L 85.457 58.616 C 86.864 57.835 88.155 57.159 89.637 56.314 C 92.438 54.716 95.275 53.376 98.032 51.823 C 98.437 51.595 114.179 43.323 115.159 43.037 L 115.16 43.036 Z " fill-rule="evenodd" fill="#F2F2F2"/></g></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,25 @@
/* eslint-env node */
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
root: true,
"rules": {
// enable additional rules
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
// override configuration set by extending "eslint:recommended"
"no-empty": "warn",
"no-cond-assign": ["error", "always"],
// disable rules from base configurations
"for-direction": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/ban-ts-comment": "off"
}
};

View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,21 @@
# asusctl
Requires `asusd` to be installed and running.
## build and install
```
npm install
npm run build && gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
npm run build && gnome-extensions enable asusctl-gnome@asus-linux.org.zip
```
You will need to restart Gnome after installing or updating
## development
```
npm run build
gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
MUTTER_DEBUG_DUMMY_MODE_SPECS=1366x768 dbus-run-session -- gnome-shell --nested --wayland
```

View File

@@ -0,0 +1,65 @@
const { build } = require("esbuild");
const fs = require("fs");
const path = require("path");
var exec = require('child_process').exec;
const AdmZip = require("adm-zip");
const metadata = require("./src/metadata.json");
build({
entryPoints: ['src/extension.ts'],
outdir: 'dist',
bundle: true,
// Do not remove the functions `enable()`, `disable()` and `init()`
treeShaking: false,
// firefox60 // Since GJS 1.53.90
// firefox68 // Since GJS 1.63.90
// firefox78 // Since GJS 1.65.90
// firefox91 // Since GJS 1.71.1
// firefox102 // Since GJS 1.73.2
target: "firefox78",
platform: "node",
// platform: "neutral",
// mainFields: ['main'],
// conditions: ['require', 'default'],
// format: 'cjs',
external: ['gi://*', 'system', 'gettext', 'cairo'],
}).then(() => {
const metaSrc = path.resolve(__dirname, "src/metadata.json");
const metaDist = path.resolve(__dirname, "dist/metadata.json");
const schemaSrc = path.resolve(__dirname, "schemas");
const schemaDist = path.resolve(__dirname, "dist/schemas");
const dbusXmlSrc = path.resolve(__dirname, "../../bindings/dbus-xml");
const dbusXmlDist = path.resolve(__dirname, "dist/resources/dbus");
const zipFilename = `${metadata.uuid}.zip`;
const zipDist = path.resolve(__dirname, zipFilename);
exec('glib-compile-schemas schemas/',
(error, stdout, stderr) => {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
});
fs.copyFileSync(metaSrc, metaDist);
fs.cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
fs.cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
const zip = new AdmZip();
zip.addLocalFolder(path.resolve(__dirname, "dist"));
zip.writeZip(zipDist);
console.log(`Build complete. Zip file: ${zipFilename}\n`);
console.log(`Install with: gnome-extensions install ${zipFilename}`)
console.log(`Update with: gnome-extensions install ${zipFilename} --force`)
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`)
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
{
"name": "asusctl-gnome",
"version": "4.7.0",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"main": "dist/extension.js",
"scripts": {
"clear": "rm -rf dist",
"build:app": "node esbuild.js",
"build": "yarn run clear && yarn run build:app",
"validate": "tsc --noEmit"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"adm-zip": "^0.5.10",
"esbuild": "^0.17.19",
"eslint": "^8.44.0",
"typescript": "^5.1.6"
},
"repository": {
"type": "git",
"url": "git+ssh://git@gitlab.com/asus-linux/asusctl.git"
},
"keywords": [
"gnome-shell",
"extension",
"asusctl",
"asus",
"rog",
"gnome",
"gjs",
"typescript"
],
"author": "Armas Spann, Marco Laux, Luke Jones",
"license": "MPL-2",
"bugs": {
"url": "https://gitlab.com/asus-linux/asusctl/issues"
},
"homepage": "https://gitlab.com/asus-linux/asusctl/desktop-extensions/gnome#readme"
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="AsusctlGnomeExtension">
<schema id="org.gnome.shell.extensions.asusctl-gnome" path="/org/gnome/shell/extensions/asusctl-gnome/" >
<key type="b" name="mini-led-enabled">
<default>false</default>
</key>
<key type="b" name="panel-od-enabled">
<default>false</default>
</key>
<key type="b" name="anime-power">
<default>false</default>
</key>
<key name="charge-level" type="u">
<range min="20" max="100"/>
<default>100</default>
</key>
<key type="s" name="primary-quickmenu-toggle">
<default>"mini-led"</default>
</key>
</schema>
</schemalist>

View File

@@ -0,0 +1 @@
../../../bindings/ts

View File

@@ -0,0 +1,112 @@
import { AnimeDbus } from "./modules/dbus/animatrix";
import { Power } from "./modules/dbus/power";
import { Supported } from "./modules/dbus/supported";
import { Platform } from "./modules/dbus/platform";
import { QuickPanelOd } from "./modules/quick_toggles/panel_od";
import { IndicateMiniLed } from "./modules/indicators/mini_led";
import { QuickMiniLed } from "./modules/quick_toggles/mini_led";
import { SliderChargeLevel } from "./modules/sliders/charge";
import { QuickAnimePower } from "./modules/quick_toggles/anime_power";
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
import { AuraDbus } from "./modules/dbus/aura";
import { AuraMenuToggle } from "./modules/quick_menus/aura";
class Extension {
private _indicateMiniLed: typeof IndicateMiniLed;
private _quickMiniLed: typeof QuickMiniLed;
private _quickPanelOd: typeof QuickPanelOd;
private _quickAnimePower: typeof QuickAnimePower;
private _featureMenuToggle: typeof FeatureMenuToggle;
private _auraModeMenuToggle: typeof AuraMenuToggle;
private _sliderCharge: typeof SliderChargeLevel;
public dbus_supported: Supported = new Supported;
public dbus_power: Power = new Power;
public dbus_aura: AuraDbus = new AuraDbus;
public dbus_anime: AnimeDbus = new AnimeDbus;
public dbus_platform: Platform = new Platform;
constructor() {
this._indicateMiniLed = null;
this._quickMiniLed = null;
this._quickPanelOd = null;
this._quickAnimePower = null;
this._sliderCharge = null;
this.dbus_supported.start();
this.dbus_aura.start();
this.dbus_platform.start();
this.dbus_power.start();
this.dbus_anime.start();
}
enable() {
if (this._featureMenuToggle == null) {
this._featureMenuToggle = new FeatureMenuToggle(this.dbus_supported, this.dbus_platform, this.dbus_anime);
}
if (this._auraModeMenuToggle == null) {
this._auraModeMenuToggle = new AuraMenuToggle(this.dbus_aura);
}
if (this.dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
// if (this._quickMiniLed == null) {
// this._quickMiniLed = new QuickMiniLed(this.dbus_platform);
// this.dbus_platform.notifyMiniLedSubscribers.push(this._quickMiniLed);
// }
if (this._indicateMiniLed == null) {
this._indicateMiniLed = new IndicateMiniLed(this.dbus_platform);
}
}
// if (this.dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
// if (this._quickPanelOd == null) {
// this._quickPanelOd = new QuickPanelOd(this.dbus_platform);
// this.dbus_platform.notifyPanelOdSubscribers.push(this._quickPanelOd);
// }
// }
// if (this.dbus_supported.supported.anime_ctrl) {
// if (this._quickAnimePower == null) {
// this._quickAnimePower = new QuickAnimePower(this._dbus_anime);
// }
// }
if (this.dbus_supported.supported.charge_ctrl.charge_level_set) {
if (this._sliderCharge == null) {
this._sliderCharge = new SliderChargeLevel(this.dbus_power);
}
}
}
disable() {
if (this._indicateMiniLed != null) {
this._indicateMiniLed.destroy();
this._indicateMiniLed = null;
}
if (this._quickMiniLed != null) {
this._quickMiniLed.destroy();
this._quickMiniLed = null;
}
if (this._quickPanelOd != null) {
this._quickPanelOd.destroy();
this._quickPanelOd = null;
}
if (this._quickAnimePower != null) {
this._quickAnimePower.destroy();
this._quickAnimePower = null;
}
if (this._sliderCharge != null) {
this._sliderCharge.destroy();
this._sliderCharge = null;
}
this.dbus_power.stop();
this.dbus_platform.stop();
this.dbus_anime.stop();
this.dbus_aura.stop();
this.dbus_supported.stop();
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function init() {
return new Extension();
}

View File

@@ -0,0 +1,11 @@
{
"name": "asusctl-gnome",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"uuid": "asusctl-gnome@asus-linux.org",
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
"version": "4.3.2",
"shell-version": [
"43", "44", "45"
]
}

View File

@@ -0,0 +1,119 @@
import { DbusBase } from "./base";
import { DeviceState, AnimBooting, Brightness, AnimAwake, AnimSleeping, AnimShutdown } from "../../bindings/anime";
export class AnimeDbus extends DbusBase {
deviceState: DeviceState = {
display_enabled: false,
display_brightness: Brightness.Med,
builtin_anims_enabled: false,
builtin_anims: {
boot: AnimBooting.GlitchConstruction,
awake: AnimAwake.BinaryBannerScroll,
sleep: AnimSleeping.BannerSwipe,
shutdown: AnimShutdown.GlitchOut
},
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAnimeStateSubscribers: any[] = [];
constructor() {
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
}
public setEnableDisplay(state: boolean | null) {
if (this.isRunning()) {
try {
// if null, toggle the current state
state = (state == null ? !this.deviceState.display_enabled : state);
if (this.deviceState.display_enabled !== state) {
this.deviceState.display_enabled = state;
}
return this.dbus_proxy.SetEnableDisplaySync(state);
} catch (e) {
//@ts-ignore
log("AniMe DBus set power failed!", e);
}
}
}
public setPowersaveAnim(state: boolean | null) {
if (this.isRunning()) {
try {
// if null, toggle the current state
state = (state == null ? !this.deviceState.builtin_anims_enabled : state);
if (this.deviceState.builtin_anims_enabled !== state) {
this.deviceState.builtin_anims_enabled = state;
}
return this.dbus_proxy.SetEnableBuiltinsSync(state);
} catch (e) {
//@ts-ignore
log("AniMe DBus set builtins failed!", e);
}
}
}
public setBrightness(brightness: Brightness) {
if (this.isRunning()) {
try {
if (this.deviceState.display_brightness !== brightness) {
this.deviceState.display_brightness = brightness;
}
return this.dbus_proxy.SetBrightnessSync(brightness);
} catch (e) {
//@ts-ignore
log("AniMe DBus set brightness failed!", e);
}
}
}
_parseData(data: any) {
if (data.length > 0) {
this.deviceState.display_enabled = data[0];
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
this.deviceState.builtin_anims_enabled = data[2];
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][2] as AnimShutdown];
}
}
public getDeviceState() {
if (this.isRunning()) {
try {
// janky shit going on with DeviceStateSync
this._parseData(this.dbus_proxy.DeviceStateSync());
} catch (e) {
//@ts-ignore
log("Failed to fetch DeviceState!", e);
}
}
return this.deviceState;
}
async start() {
await super.start();
this.getDeviceState();
this.dbus_proxy.connectSignal(
"NotifyDeviceState",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(proxy: any = null, name: string, data: string) => {
if (proxy) {
// idiot xml parsing mneans the get is not nested while this is
this._parseData(data[0]);
this.notifyAnimeStateSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,284 @@
import { AuraDevRog1, AuraDevTuf, AuraDevice, AuraEffect, AuraModeNum, AuraPower, AuraPowerDev, AuraZone, Direction, PowerZones, Speed } from "../../bindings/aura";
import { DbusBase } from "./base";
export class AuraDbus extends DbusBase {
public device: AuraDevice = AuraDevice.Unknown;
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map;
public leds_powered: AuraPowerDev = {
tuf: [],
old_rog: [],
rog: {
keyboard: {
zone: PowerZones.Keyboard,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
logo: {
zone: PowerZones.Logo,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
lightbar: {
zone: PowerZones.Lightbar,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
lid: {
zone: PowerZones.Lid,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
rear_glow: {
zone: PowerZones.RearGlow,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
}
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAuraModeSubscribers: any[] = [];
public notifyAuraPowerSubscribers: any[] = [];
constructor() {
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
}
public getDevice() {
if (this.isRunning()) {
try {
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
//@ts-ignore
log("LED device: " + this.device);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parsePowerStates(data: any[]) {
const power: AuraPowerDev = this.leds_powered;
power.tuf = data[0].map((value: string) => {
return AuraDevTuf[value as AuraDevTuf];
});
power.old_rog = data[1].map((value: string) => {
return AuraDevRog1[value as AuraDevRog1];
});
power.rog = {
keyboard: {
zone: PowerZones[data[2][0][0] as PowerZones],
boot: data[2][0][1],
awake: data[2][0][2],
sleep: data[2][0][3],
shutdown: data[2][0][4]
},
logo: {
zone: PowerZones[data[2][1][0] as PowerZones],
boot: data[2][1][1],
awake: data[2][1][2],
sleep: data[2][1][3],
shutdown: data[2][1][4]
},
lightbar: {
zone: PowerZones[data[2][2][0] as PowerZones],
boot: data[2][2][1],
awake: data[2][2][2],
sleep: data[2][2][3],
shutdown: data[2][2][4]
},
lid: {
zone: PowerZones[data[2][3][0] as PowerZones],
boot: data[2][3][1],
awake: data[2][3][2],
sleep: data[2][3][3],
shutdown: data[2][3][4]
},
rear_glow: {
zone: PowerZones[data[2][4][0] as PowerZones],
boot: data[2][4][1],
awake: data[2][4][2],
sleep: data[2][4][3],
shutdown: data[2][4][4]
}
};
return power;
}
public getLedPower() {
if (this.isRunning()) {
try {
const data = this.dbus_proxy.LedPowerSync();
this.leds_powered = this._parsePowerStates(data);
//@ts-ignore
log("LED power tuf: " + this.leds_powered.tuf);
//@ts-ignore
log("LED power x1866: " + this.leds_powered.old_rog);
//@ts-ignore
log("LED power x19b6: " + this.leds_powered.rog);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public getLedMode() {
if (this.isRunning()) {
try {
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
//@ts-ignore
log("Current LED mode:", this.current_aura_mode);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public setLedMode(mode: AuraEffect) {
if (this.isRunning()) {
try {
this.dbus_proxy.SetLedModeSync([
mode.mode,
mode.zone,
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
mode.speed,
mode.direction]);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parseAuraEffect(data: any[]) {
const aura: AuraEffect = {
mode: AuraModeNum[data[0] as AuraModeNum],
zone: AuraZone[data[1] as AuraZone],
colour1: {
r: parseInt(data[2][0]),
g: parseInt(data[2][1]),
b: parseInt(data[2][2]),
},
colour2: {
r: parseInt(data[3][0]),
g: parseInt(data[3][1]),
b: parseInt(data[3][2]),
},
speed: Speed[data[4] as Speed],
direction: Direction[data[5] as Direction],
};
return aura;
}
// Return a list of the available modes, and the current settings for each
public getLedModes() {
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
if (this.isRunning()) {
try {
const _data = this.dbus_proxy.LedModesSync();
for (const key in _data[0]) {
const data = _data[0][key];
const aura: AuraEffect = this._parseAuraEffect(data);
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
}
for (const [key, value] of this.aura_modes) {
//@ts-ignore
log(key, value.zone, value.colour1.r, value.speed, value.direction);
}
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
async start() {
try {
await super.start();
this.getDevice();
this.getLedPower();
this.getLedMode();
this.getLedModes();
//@ts-ignore
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
this.dbus_proxy.connectSignal(
"NotifyLed",
(proxy: any = null, name: string, data: any) => {
if (proxy) {
const aura: AuraEffect = this._parseAuraEffect(data[0]);
this.current_aura_mode = aura.mode;
this.aura_modes.set(aura.mode, aura);
//@ts-ignore
log("LED data has changed to ", aura.mode, aura.zone, aura.colour1.r, aura.speed, aura.direction);
this.notifyAuraModeSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.dbus_proxy.connectSignal(
"NotifyPowerStates",
(proxy: any = null, name: string, data: any) => {
if (proxy) {
const power: AuraPowerDev = this._parsePowerStates(data[0]);
this.leds_powered = power;
switch (this.device) {
case AuraDevice.Tuf:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.tuf);
break;
case AuraDevice.X1854:
case AuraDevice.X1869:
case AuraDevice.X18c6:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.old_rog);
break;
case AuraDevice.X19b6:
case AuraDevice.X1a30:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
break;
default:
break;
}
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
this.notifyAuraPowerSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
} catch (e) {
//@ts-ignore
log("Supported DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,52 @@
declare const imports: any;
import * as Resources from "../resources";
const { Gio } = imports.gi;
export class DbusBase {
dbus_proxy: any = null; // type: Gio.DbusProxy
connected = false;
xml_resource = "";
dbus_path = "";
constructor(resource: string, dbus_path: string) {
this.xml_resource = resource;
this.dbus_path = dbus_path;
}
async start() {
//@ts-ignore
log(`Starting ${this.dbus_path} dbus module`);
try {
const xml = Resources.File.DBus(this.xml_resource);
this.dbus_proxy = new Gio.DBusProxy.makeProxyWrapper(xml)(
Gio.DBus.system,
"org.asuslinux.Daemon",
this.dbus_path,
);
this.connected = true;
//@ts-ignore
log(`${this.dbus_path} client started successfully.`);
} catch (e) {
//@ts-ignore
logError(`${this.xml_resource} dbus init failed!`, e);
}
}
async stop() {
//@ts-ignore
log(`Stopping ${this.xml_resource} dbus module`);
if (this.connected) {
this.dbus_proxy.destroy();
this.connected = false;
this.dbus_proxy = null;
}
}
isRunning(): boolean {
return this.connected;
}
}

View File

@@ -0,0 +1,202 @@
import * as bios from "../../bindings/platform";
import { DbusBase } from "./base";
// TODO: add callbacks for notifications
export class Platform extends DbusBase {
bios: bios.RogBiosSupportedFunctions = {
post_sound: false,
gpu_mux: false,
panel_overdrive: false,
dgpu_disable: false,
egpu_enable: false,
mini_led_mode: false
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyPanelOdSubscribers: any[] = [];
public notifyPostBootSoundSubscribers: any[] = [];
public notifyMiniLedSubscribers: any[] = [];
public notifyGpuMuxSubscribers: any[] = [];
constructor() {
super("org-asuslinux-platform-4", "/org/asuslinux/Platform");
}
public getPostBootSound() {
if (this.isRunning()) {
try {
this.bios.post_sound = this.dbus_proxy.PostBootSoundSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get POST Boot Sound state!", e);
}
}
return this.bios.post_sound;
}
public setPostBootSound(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.post_sound) {
this.bios.post_sound = state;
}
return this.dbus_proxy.SetPostBootSoundSync(state);
} catch (e) {
//@ts-ignore
log("Platform DBus set Post Boot Sound failed!", e);
}
}
}
public getGpuMuxMode() {
if (this.isRunning()) {
try {
this.bios.gpu_mux = this.dbus_proxy.GpuMuxModeSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get MUX state!", e);
}
}
return this.bios.gpu_mux;
}
public setGpuMuxMode(state: boolean) {
if (this.isRunning()) {
try {
if (!state !== this.bios.gpu_mux) {
this.bios.gpu_mux = !state;
}
return this.dbus_proxy.SetGpuMuxModeSync(!state);
} catch (e) {
//@ts-ignore
log("Switching the MUX failed!", e);
}
}
}
public getPanelOd() {
if (this.isRunning()) {
try {
this.bios.panel_overdrive = this.dbus_proxy.PanelOdSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get Overdrive state!", e);
}
}
return this.bios.panel_overdrive;
}
public setPanelOd(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.panel_overdrive) {
this.bios.panel_overdrive = state;
}
return this.dbus_proxy.SetPanelOdSync(state);
} catch (e) {
//@ts-ignore
log("Overdrive DBus set overdrive state failed!", e);
}
}
}
public getMiniLedMode() {
if (this.isRunning()) {
try {
this.bios.mini_led_mode = this.dbus_proxy.MiniLedModeSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get Overdrive state!", e);
}
}
return this.bios.mini_led_mode;
}
public setMiniLedMode(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.mini_led_mode) {
this.bios.mini_led_mode = state;
}
return this.dbus_proxy.SetMiniLedModeSync(state);
} catch (e) {
//@ts-ignore
log("setMiniLedMode failed!", e);
}
}
}
async start() {
try {
await super.start();
this.getPostBootSound();
this.dbus_proxy.connectSignal(
"NotifyPostBootSound",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`PostBootSound changed to ${data}`);
this.notifyPostBootSoundSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getPanelOd();
this.dbus_proxy.connectSignal(
"NotifyPanelOd",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`NotifyPanelOd has changed to ${data}.`);
this.notifyPanelOdSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getMiniLedMode();
this.dbus_proxy.connectSignal(
"NotifyMiniLedMode",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`MiniLedMode has changed to ${data}.`);
this.notifyMiniLedSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getGpuMuxMode();
this.dbus_proxy.connectSignal(
"NotifyGpuMuxMode",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`MUX has changed to ${data}.`);
this.notifyGpuMuxSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
} catch (e) {
//@ts-ignore
log("Platform DBus init failed!", e);
}
}
async stop() {
await super.stop();
this.bios.post_sound = false;
this.bios.panel_overdrive = false;
this.bios.mini_led_mode = false;
this.bios.gpu_mux = false;
}
}

View File

@@ -0,0 +1,99 @@
import { DbusBase } from "./base";
// function getMethods(obj: { [x: string]: { toString: () => string; }; }) {
// var result = [];
// for (var id in obj) {
// try {
// if (typeof(obj[id]) == "function") {
// result.push(id + ": " + obj[id].toString());
// }
// } catch (err) {
// result.push(id + ": inaccessible");
// }
// }
// return result;
// }
export class Power extends DbusBase {
chargeLimit = 100;
mainsOnline = false;
constructor() {
super("org-asuslinux-power-4", "/org/asuslinux/Power");
}
public getChargingLimit() {
if (this.isRunning()) {
try {
this.chargeLimit = this.dbus_proxy.ChargeControlEndThresholdSync();
} catch (e) {
//@ts-ignore
log("Failed to fetch Charging Limit!", e);
}
}
return this.chargeLimit;
}
public setChargingLimit(limit: number) {
if (this.isRunning()) {
try {
if (limit > 0 && this.chargeLimit !== limit) {
// update state
this.chargeLimit = limit;
}
return this.dbus_proxy.SetChargeControlEndThresholdSync(limit);
} catch (e) {
//@ts-ignore
log("Profile DBus set power profile failed!", e);
}
}
}
public getMainsOnline() {
if (this.isRunning()) {
try {
this.mainsOnline = this.dbus_proxy.MainsOnlineSync();
} catch (e) {
//@ts-ignore
log("Failed to fetch MainsLonline!", e);
}
}
return this.mainsOnline;
}
async start() {
try {
await super.start();
this.getChargingLimit();
this.dbus_proxy.connectSignal(
"NotifyChargeControlEndThreshold",
(proxy: any = null, name: string, data: string) => {
if (proxy) {
//@ts-ignore
log(`Charging Limit has changed to ${data}% (${name}).`);
this.chargeLimit = parseInt(data);
}
}
);
this.dbus_proxy.connectSignal(
"NotifyMainsOnline",
(proxy: any = null, name: string, data: string) => {
if (proxy) {
//@ts-ignore
log(`NotifyMainsOnline has changed to ${data}% (${name}).`);
this.mainsOnline = parseInt(data) == 1 ? true : false;
}
}
);
} catch (e) {
//@ts-ignore
log("Charging Limit DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,106 @@
import { SupportedFunctions, AdvancedAura } from "../../bindings/platform";
import { AuraDevice, AuraModeNum, AuraZone, PowerZones } from "../../bindings/aura";
import { DbusBase } from "./base";
export class Supported extends DbusBase {
// False,
// (True,),
// (True, True),
// ('X19b6',
// True,
// ['Static',
// 'Breathe',
// 'Strobe',
// 'Rainbow',
// 'Star',
// 'Rain',
// 'Highlight',
// 'Laser',
// 'Ripple',
// 'Pulse',
// 'Comet',
// 'Flash'],
// [],
// 'PerKey',
// ['Keyboard', 'Lightbar', 'Logo', 'RearGlow']),
// (False, True, True, True, False, True)
supported: SupportedFunctions = {
anime_ctrl: false,
charge_ctrl: {
charge_level_set: false
},
platform_profile: {
platform_profile: false,
fan_curves: false
},
keyboard_led: {
dev_id: AuraDevice.Unknown,
brightness: false,
basic_modes: [],
basic_zones: [],
advanced_type: AdvancedAura.None
},
rog_bios_ctrl: {
post_sound: false,
gpu_mux: false,
panel_overdrive: false,
dgpu_disable: false,
egpu_enable: false,
mini_led_mode: false
}
};
constructor() {
super("org-asuslinux-supported-4", "/org/asuslinux/Supported");
}
public getSupported() {
if (this.isRunning()) {
try {
const _data = this.dbus_proxy.SupportedFunctionsSync();
this.supported.anime_ctrl = _data[0];
this.supported.charge_ctrl.charge_level_set = _data[1];
this.supported.platform_profile.platform_profile = _data[2][0];
this.supported.platform_profile.fan_curves = _data[2][1];
this.supported.keyboard_led.dev_id = AuraDevice[_data[3][0] as AuraDevice];
this.supported.keyboard_led.brightness = _data[3][1];
this.supported.keyboard_led.basic_modes = _data[3][2].map(function (value: string) {
return AuraModeNum[value as AuraModeNum];
});
this.supported.keyboard_led.basic_zones = _data[3][3].map(function (value: string) {
return AuraZone[value as AuraZone];
});
this.supported.keyboard_led.advanced_type = AdvancedAura[_data[3][4] as AdvancedAura];
this.supported.keyboard_led.power_zones = _data[3][5].map(function (value: string) {
return PowerZones[value as PowerZones];
});
this.supported.rog_bios_ctrl.post_sound = _data[4][0];
this.supported.rog_bios_ctrl.gpu_mux = _data[4][1];
this.supported.rog_bios_ctrl.panel_overdrive = _data[4][2];
this.supported.rog_bios_ctrl.dgpu_disable = _data[4][3];
this.supported.rog_bios_ctrl.egpu_enable = _data[4][4];
this.supported.rog_bios_ctrl.mini_led_mode = _data[4][5];
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
async start() {
try {
await super.start();
this.getSupported();
} catch (e) {
//@ts-ignore
log("Supported DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,15 @@
declare const imports: any;
const { QuickToggle } = imports.ui.quickSettings;
const QuickSettingsMenu = imports.ui.main.panel.statusArea.quickSettings;
export function addQuickSettingsItems(items: [typeof QuickToggle], width = 1) {
// Add the items with the built-in function
QuickSettingsMenu._addItems(items, width);
// Ensure the tile(s) are above the background apps menu
for (const item of items) {
QuickSettingsMenu.menu._grid.set_child_below_sibling(item,
QuickSettingsMenu._backgroundApps.quickSettingsItems[0]);
}
}

View File

@@ -0,0 +1,28 @@
declare const imports: any;
// REF: https://gjs.guide/extensions/development/creating.html
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const { SystemIndicator } = imports.ui.quickSettings;
const QuickSettingsMenu = imports.ui.main.panel.statusArea.quickSettings;
export const IndicateMiniLed = GObject.registerClass(
class IndicateMiniLed extends SystemIndicator {
constructor() {
super();
// Create the icon for the indicator
this._indicator = this._addIndicator();
this._indicator.icon_name = "selection-mode-symbolic";
// Showing the indicator when the feature is enabled
this._settings = ExtensionUtils.getSettings();
this._settings.bind("mini-led-enabled",
this._indicator, "visible",
Gio.SettingsBindFlags.DEFAULT);
// Add the indicator to the panel and the toggle to the menu
QuickSettingsMenu._indicators.add_child(this);
}
});

View File

@@ -0,0 +1,86 @@
declare const imports: any;
import { AnimeDbus } from "../dbus/animatrix";
const { GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const PopupMenu = imports.ui.popupMenu;
export const MenuToggleAnimePower = GObject.registerClass(
class MenuToggleAnimePower extends PopupMenu.PopupSwitchMenuItem {
private _dbus_anime: AnimeDbus;
public toggle_callback = () => {};
constructor(dbus_anime: AnimeDbus) {
super(
"AniMatrix Display Power", dbus_anime.deviceState.display_enabled
);
this._dbus_anime = dbus_anime;
this.label = "AniMatrix Display Power";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"toggled", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this.sync();
}
_toggleMode() {
this._dbus_anime.getDeviceState();
if (this.state !== this._dbus_anime.deviceState.display_enabled)
this._dbus_anime.setEnableDisplay(this.state);
this.toggle_callback();
}
sync() {
this._dbus_anime.getDeviceState();
const checked = this._dbus_anime.deviceState.display_enabled;
this.setToggleState(checked);
}
});
export const MenuToggleAnimeBuiltins = GObject.registerClass(
class MenuToggleAnimeBuiltins extends PopupMenu.PopupSwitchMenuItem {
private _dbus_anime: AnimeDbus;
public toggle_callback = () => {};
constructor(dbus_anime: AnimeDbus) {
super(
"AniMatrix Powersave Animation", dbus_anime.deviceState.builtin_anims_enabled
);
this._dbus_anime = dbus_anime;
this.label = "AniMatrix Powersave Animation";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"toggled", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this.sync();
}
_toggleMode() {
this._dbus_anime.getDeviceState();
if (this.state !== this._dbus_anime.deviceState.builtin_anims_enabled)
this._dbus_anime.setPowersaveAnim(this.state);
this.toggle_callback();
}
sync() {
this._dbus_anime.getDeviceState();
const checked = this._dbus_anime.deviceState.display_enabled;
this.setToggleState(checked);
}
});

View File

@@ -0,0 +1,46 @@
declare const imports: any;
import { Platform } from "../dbus/platform";
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const PopupMenu = imports.ui.popupMenu;
export const MenuToggleMiniLed = GObject.registerClass(
class MenuToggleMiniLed extends PopupMenu.PopupSwitchMenuItem {
private _dbus_platform: Platform;
public toggle_callback = () => {};
constructor(dbus_platform: Platform) {
super("MiniLED", dbus_platform.bios.mini_led_mode);
this._dbus_platform = dbus_platform;
this.label = "MiniLED";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"toggled", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this.sync();
}
_toggleMode() {
this._dbus_platform.getMiniLedMode();
const state = this._dbus_platform.bios.mini_led_mode;
if (this.state !== state)
this._dbus_platform.setMiniLedMode(this.state);
this.toggle_callback();
}
sync() {
this._dbus_platform.getMiniLedMode();
const toggled = this._dbus_platform.bios.mini_led_mode;
this.setToggleState(toggled);
}
});

View File

@@ -0,0 +1,46 @@
declare const imports: any;
import { Platform } from "../dbus/platform";
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const PopupMenu = imports.ui.popupMenu;
export const MenuTogglePanelOd = GObject.registerClass(
class MenuTogglePanelOd extends PopupMenu.PopupSwitchMenuItem {
private _dbus_platform: Platform;
public toggle_callback = () => {};
constructor(dbus_platform: Platform) {
super("Panel Overdrive", dbus_platform.bios.panel_overdrive);
this._dbus_platform = dbus_platform;
this.label = "Panel Overdrive";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"toggled", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this.sync();
}
_toggleMode() {
this._dbus_platform.getPanelOd();
const state = this._dbus_platform.bios.panel_overdrive;
if (this.state !== state)
this._dbus_platform.setPanelOd(this.state);
this.toggle_callback();
}
sync() {
this._dbus_platform.getPanelOd();
const toggled = this._dbus_platform.bios.panel_overdrive;
this.setToggleState(toggled);
}
});

View File

@@ -0,0 +1,86 @@
declare const imports: any;
// REF: https://gjs.guide/extensions/development/creating.html
import { addQuickSettingsItems } from "../helpers";
import { AuraDbus } from "../dbus/aura";
import { AuraEffect, AuraModeNum } from "../../bindings/aura";
const { GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
// const Me = ExtensionUtils.getCurrentExtension();
// const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const QuickSettings = imports.ui.quickSettings;
export const AuraMenuToggle = GObject.registerClass(
class AuraMenuToggle extends QuickSettings.QuickMenuToggle {
private _dbus_aura: AuraDbus;
private _last_mode: AuraModeNum = AuraModeNum.Static;
constructor(dbus_aura: AuraDbus) {
super({
title: "Aura Modes",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_aura = dbus_aura;
this.connectObject(
"destroy", () => this._settings.run_dispose(),
this);
this.menu.setHeader("selection-mode-symbolic", this._dbus_aura.current_aura_mode);
this._settings = ExtensionUtils.getSettings();
this._itemsSection = new PopupMenu.PopupMenuSection();
this._dbus_aura.aura_modes.forEach((mode, key) => {
this._itemsSection.addAction(key, () => {
this._dbus_aura.setLedMode(mode);
this.sync();
}, "");
});
this.menu.addMenuItem(this._itemsSection);
// Add an entry-point for more settings
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
// const settingsItem = this.menu.addAction("More Settings",
// () => ExtensionUtils.openPrefs());
// // Ensure the settings are unavailable when the screen is locked
// settingsItem.visible = Main.sessionMode.allowSettings;
// this.menu._settingsActions[Me.uuid] = settingsItem;
this.connectObject(
"clicked", () => {
let mode: AuraEffect | undefined;
if (this._dbus_aura.current_aura_mode == AuraModeNum.Static) {
mode = this._dbus_aura.aura_modes.get(this._last_mode);
} else {
mode = this._dbus_aura.aura_modes.get(AuraModeNum.Static);
}
if (mode != undefined) {
this._dbus_aura.setLedMode(mode);
this.sync();
}
},
this);
this._dbus_aura.notifyAuraModeSubscribers.push(this);
this.sync();
addQuickSettingsItems([this]);
}
sync() {
const checked = this._dbus_aura.current_aura_mode != AuraModeNum.Static;
this.title = this._dbus_aura.current_aura_mode;
if (this._last_mode != this._dbus_aura.current_aura_mode && this._dbus_aura.current_aura_mode != AuraModeNum.Static) {
this._last_mode = this._dbus_aura.current_aura_mode;
}
if (this.checked !== checked)
this.set({ checked });
}
});

View File

@@ -0,0 +1,179 @@
declare const imports: any;
// REF: https://gjs.guide/extensions/development/creating.html
import { AnimeDbus } from "../dbus/animatrix";
import { Supported } from "../dbus/supported";
import { Platform } from "../dbus/platform";
import { addQuickSettingsItems } from "../helpers";
import { MenuToggleAnimeBuiltins, MenuToggleAnimePower } from "../menu_toggles/anime";
import { MenuTogglePanelOd } from "../menu_toggles/panel_od";
import { MenuToggleMiniLed } from "../menu_toggles/mini_led";
const { GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
// const Me = ExtensionUtils.getCurrentExtension();
// const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const QuickSettings = imports.ui.quickSettings;
export const FeatureMenuToggle = GObject.registerClass(
class FeatureMenuToggle extends QuickSettings.QuickMenuToggle {
private _dbus_supported: Supported;
private _dbus_platform: Platform;
private _dbus_anime: AnimeDbus;
public miniLed: typeof MenuToggleMiniLed;
public panelOd: typeof MenuTogglePanelOd;
public animeDisplayPower: typeof MenuToggleAnimePower;
public animePowersaveAnim: typeof MenuToggleAnimeBuiltins;
private primary = "mini-led";
constructor(dbus_supported: Supported, dbus_platform: Platform, dbus_anime: AnimeDbus) {
super({
title: "Laptop",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_supported = dbus_supported;
this._dbus_platform = dbus_platform;
this._dbus_anime = dbus_anime;
this.menu.setHeader("selection-mode-symbolic", "Laptop features");
this._settings = ExtensionUtils.getSettings();
this.primary = this._settings.get_string("primary-quickmenu-toggle");
// TODO: temporary block
if (this.primary == "mini-led" && !this._dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
this.primary = "panel-od";
} else if (this.primary == "panel-od" && !this._dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
this.primary = "anime-power";
} else if (this.primary == "anime-power" && !this._dbus_supported.supported.anime_ctrl) {
this.primary = "mini-led";
} else if (this.primary.length == 0) {
this.primary = "panel-od";
}
this.connectObject(
"destroy", () => this._settings.run_dispose(),
this);
this._settings.connect('changed::primary-quickmenu-toggle',
this.sync);
this._settings.set_string("primary-quickmenu-toggle", this.primary);
this._itemsSection = new PopupMenu.PopupMenuSection();
if (this._dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
if (this.miniLed == null) {
this.miniLed = new MenuToggleMiniLed(this._dbus_platform);
this._dbus_platform.notifyMiniLedSubscribers.push(this.miniLed);
this._itemsSection.addMenuItem(this.miniLed);
this._dbus_platform.notifyMiniLedSubscribers.push(this);
this.miniLed.toggle_callback = () => {
this.primary = "mini-led";
this.sync();
}
}
}
if (this._dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
if (this.panelOd == null) {
this.panelOd = new MenuTogglePanelOd(this._dbus_platform);
this._dbus_platform.notifyPanelOdSubscribers.push(this.panelOd);
this._itemsSection.addMenuItem(this.panelOd);
this._dbus_platform.notifyPanelOdSubscribers.push(this);
this.panelOd.toggle_callback = () => {
this.primary = "panel-od";
this.sync();
}
}
}
if (this._dbus_supported.supported.anime_ctrl) {
if (this.animeDisplayPower == null) {
this.animeDisplayPower = new MenuToggleAnimePower(this._dbus_anime);
this._dbus_anime.notifyAnimeStateSubscribers.push(this.animeDisplayPower);
this._itemsSection.addMenuItem(this.animeDisplayPower);
this._dbus_anime.notifyAnimeStateSubscribers.push(this);
this.animeDisplayPower.toggle_callback = () => {
this.primary = "anime-power";
this.sync();
}
}
if (this.animePowersaveAnim == null) {
this.animePowersaveAnim = new MenuToggleAnimeBuiltins(this._dbus_anime);
this._dbus_anime.notifyAnimeStateSubscribers.push(this.animePowersaveAnim);
this._itemsSection.addMenuItem(this.animePowersaveAnim);
}
}
this.connectObject(
"clicked", () => {
this._toggle();
},
this);
this.menu.addMenuItem(this._itemsSection);
// // Add an entry-point for more settings
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
// const settingsItem = this.menu.addAction("More Settings",
// () => ExtensionUtils.openPrefs());
// // Ensure the settings are unavailable when the screen is locked
// settingsItem.visible = Main.sessionMode.allowSettings;
// this.menu._settingsActions[Me.uuid] = settingsItem;
this.sync();
addQuickSettingsItems([this]);
}
_toggle() {
if (this.primary == "mini-led" && this.miniLed != null) {
this._dbus_platform.getMiniLedMode();
const checked = this._dbus_platform.bios.mini_led_mode;
if (this.checked !== checked)
this._dbus_platform.setMiniLedMode(this.checked);
}
if (this.primary == "panel-od" && this.panelOd != null) {
this._dbus_platform.getPanelOd();
const checked = this._dbus_platform.bios.panel_overdrive;
if (this.checked !== checked)
this._dbus_platform.setPanelOd(this.checked);
}
if (this.primary == "anime-power" && this.animeDisplayPower != null) {
this._dbus_anime.getDeviceState();
const checked = this._dbus_anime.deviceState.display_enabled;
if (this.checked !== checked)
this._dbus_anime.setEnableDisplay(this.checked);
}
}
sync() {
let checked = false;
if (this.primary == "mini-led" && this.miniLed != null) {
this.title = this.miniLed.label;
checked = this._dbus_platform.bios.mini_led_mode;
}
if (this.primary == "panel-od" && this.panelOd != null) {
this.title = this.panelOd.label;
checked = this._dbus_platform.bios.panel_overdrive;
}
if (this.primary == "anime-power" && this.animeDisplayPower != null) {
this.title = this.animeDisplayPower.label;
checked = this._dbus_anime.deviceState.display_enabled;
}
// if (this.animePowersaveAnim != null) {
// }
if (this.checked !== checked)
this.set({ checked });
}
});

View File

@@ -0,0 +1,56 @@
declare const imports: any;
import { AnimeDbus } from "../dbus/animatrix";
import { addQuickSettingsItems } from "../helpers";
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const { QuickToggle } = imports.ui.quickSettings;
export const QuickAnimePower = GObject.registerClass(
class QuickAnimePower extends QuickToggle {
private _dbus_anime: AnimeDbus;
constructor(dbus_anime: AnimeDbus) {
super({
title: "AniMatrix Power",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_anime = dbus_anime;
this.label = "AniMatrix Power";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"clicked", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this._settings.bind("anime-power",
this, "checked",
Gio.SettingsBindFlags.DEFAULT);
this.sync();
addQuickSettingsItems([this]);
}
_toggleMode() {
this._dbus_anime.getDeviceState();
const checked = this._dbus_anime.deviceState.display_enabled;
if (this.checked !== checked)
this._dbus_anime.setEnableDisplay(this.checked);
}
sync() {
this._dbus_anime.getDeviceState();
const checked = this._dbus_anime.deviceState.display_enabled;
if (this.checked !== checked)
this.set({ checked });
}
});

View File

@@ -0,0 +1,54 @@
declare const imports: any;
import { Platform } from "../dbus/platform";
import { addQuickSettingsItems } from "../helpers";
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const { QuickToggle } = imports.ui.quickSettings;
export const QuickMiniLed = GObject.registerClass(
class QuickMiniLed extends QuickToggle {
private _dbus_platform: Platform;
constructor(dbus_platform: Platform) {
super({
title: "MiniLED",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_platform = dbus_platform;
this.label = "MiniLED";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"clicked", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this._settings.bind("mini-led-enabled",
this, "checked",
Gio.SettingsBindFlags.DEFAULT);
this.sync();
addQuickSettingsItems([this]);
}
_toggleMode() {
const checked = this._dbus_platform.getMiniLedMode();
if (this.checked !== checked)
this._dbus_platform.setMiniLedMode(this.checked);
}
sync() {
const checked = this._dbus_platform.getMiniLedMode();
if (this.checked !== checked)
this.set({ checked });
}
});

View File

@@ -0,0 +1,54 @@
declare const imports: any;
import { Platform } from "../dbus/platform";
import { addQuickSettingsItems } from "../helpers";
const { GObject, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const { QuickToggle } = imports.ui.quickSettings;
export const QuickPanelOd = GObject.registerClass(
class QuickPanelOd extends QuickToggle {
private _dbus_platform: Platform;
constructor(dbus_platform: Platform) {
super({
title: "Panel Overdrive",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_platform = dbus_platform;
this.label = "Panel Overdrive";
this._settings = ExtensionUtils.getSettings();
this.connectObject(
"destroy", () => this._settings.run_dispose(),
"clicked", () => this._toggleMode(),
this);
this.connect("destroy", () => {
this.destroy();
});
this._settings.bind("panel-od-enabled",
this, "checked",
Gio.SettingsBindFlags.DEFAULT);
this.sync();
addQuickSettingsItems([this]);
}
_toggleMode() {
const checked = this._dbus_platform.getPanelOd();
if (this.checked !== checked)
this._dbus_platform.setPanelOd(this.checked);
}
sync() {
const checked = this._dbus_platform.getPanelOd();
if (this.checked !== checked)
this.set({ checked });
}
});

View File

@@ -0,0 +1,20 @@
declare const imports: any;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const GLib = imports.gi.GLib;
export class File {
public static DBus(name: string) {
const file = `${Me.path}/resources/dbus/${name}.xml`;
try {
const [_ok, bytes] = GLib.file_get_contents(file);
if (!_ok)
//@ts-ignore
log(`Couldn't read contents of "${file}"`);
return _ok ? imports.byteArray.toString(bytes) : null;
} catch (e) {
//@ts-ignore
log(`Failed to load "${file}"`, e);
}
}
}

View File

@@ -0,0 +1,60 @@
import { Power } from "../dbus/power";
import { addQuickSettingsItems } from "../helpers";
declare const imports: any;
const { GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const QuickSettings = imports.ui.quickSettings;
export const SliderChargeLevel = GObject.registerClass(
class SliderChargeLevel extends QuickSettings.QuickSlider {
private _dbus_power: Power;
constructor(dbus_power: Power) {
super({
iconName: "selection-mode-symbolic",
});
this._dbus_power = dbus_power;
this._sliderChangedId = this.slider.connect("drag-end",
this._onSliderChanged.bind(this));
// Binding the slider to a GSettings key
this._settings = ExtensionUtils.getSettings();
this._settings.connect("changed::charge-level",
this._onSettingsChanged.bind(this));
// Set an accessible name for the slider
this.slider.accessible_name = "Charge level";
this._sync();
this._onSettingsChanged();
addQuickSettingsItems([this], 2);
}
_onSettingsChanged() {
// Prevent the slider from emitting a change signal while being updated
this.slider.block_signal_handler(this._sliderChangedId);
this.slider.value = this._settings.get_uint("charge-level") / 100.0;
this.slider.unblock_signal_handler(this._sliderChangedId);
}
_onSliderChanged() {
// Assuming our GSettings holds values between 0..100, adjust for the
// slider taking values between 0..1
const percent = Math.floor(this.slider.value * 100);
const stored = Math.floor(this._settings.get_uint("charge-level") / 100.0);
if (this.slider.value !== stored)
this._dbus_power.setChargingLimit(percent);
this._settings.set_uint("charge-level", percent);
}
_sync() {
const value = this._dbus_power.getChargingLimit();
if (this.slider.value !== value / 100)
this._settings.set_uint("charge-level", value);
}
});

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"lib": [
"es2019"
],
"types": [],
"target": "es2019",
"module": "CommonJS",
"moduleResolution": "node",
"declaration": true,
"removeComments": true,
"strict": true,
"allowJs": true
},
"files": [
"./src/extension.ts",
],
"include": [
"src/*.ts",
"src/**/*.ts"
]
}

View File

@@ -0,0 +1,940 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@aashutoshrathi/word-wrap@^1.2.3":
version "1.2.6"
resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz"
integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
"@esbuild/linux-x64@0.17.19":
version "0.17.19"
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz"
integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
dependencies:
eslint-visitor-keys "^3.3.0"
"@eslint-community/regexpp@^4.4.0":
version "4.5.1"
resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz"
integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==
"@eslint/eslintrc@^2.1.0":
version "2.1.0"
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz"
integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.6.0"
globals "^13.19.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@8.44.0":
version "8.44.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz"
integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==
"@humanwhocodes/config-array@^0.11.10":
version "0.11.10"
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz"
integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==
dependencies:
"@humanwhocodes/object-schema" "^1.2.1"
debug "^4.1.1"
minimatch "^3.0.5"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/object-schema@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
version "1.2.8"
resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@types/json-schema@^7.0.9":
version "7.0.12"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz"
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
"@types/semver@^7.3.12":
version "7.5.0"
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz"
integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
"@typescript-eslint/eslint-plugin@^5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz"
integrity sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==
dependencies:
"@eslint-community/regexpp" "^4.4.0"
"@typescript-eslint/scope-manager" "5.60.1"
"@typescript-eslint/type-utils" "5.60.1"
"@typescript-eslint/utils" "5.60.1"
debug "^4.3.4"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
natural-compare-lite "^1.4.0"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz"
integrity sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==
dependencies:
"@typescript-eslint/scope-manager" "5.60.1"
"@typescript-eslint/types" "5.60.1"
"@typescript-eslint/typescript-estree" "5.60.1"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz"
integrity sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==
dependencies:
"@typescript-eslint/types" "5.60.1"
"@typescript-eslint/visitor-keys" "5.60.1"
"@typescript-eslint/type-utils@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz"
integrity sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==
dependencies:
"@typescript-eslint/typescript-estree" "5.60.1"
"@typescript-eslint/utils" "5.60.1"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz"
integrity sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==
"@typescript-eslint/typescript-estree@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz"
integrity sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==
dependencies:
"@typescript-eslint/types" "5.60.1"
"@typescript-eslint/visitor-keys" "5.60.1"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz"
integrity sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.60.1"
"@typescript-eslint/types" "5.60.1"
"@typescript-eslint/typescript-estree" "5.60.1"
eslint-scope "^5.1.1"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.60.1":
version "5.60.1"
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz"
integrity sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==
dependencies:
"@typescript-eslint/types" "5.60.1"
eslint-visitor-keys "^3.3.0"
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0:
version "8.9.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz"
integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==
adm-zip@^0.5.10:
version "0.5.10"
resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz"
integrity sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==
ajv@^6.10.0, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
braces@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
dependencies:
path-type "^4.0.0"
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
dependencies:
esutils "^2.0.2"
esbuild@^0.17.19:
version "0.17.19"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz"
integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==
optionalDependencies:
"@esbuild/android-arm" "0.17.19"
"@esbuild/android-arm64" "0.17.19"
"@esbuild/android-x64" "0.17.19"
"@esbuild/darwin-arm64" "0.17.19"
"@esbuild/darwin-x64" "0.17.19"
"@esbuild/freebsd-arm64" "0.17.19"
"@esbuild/freebsd-x64" "0.17.19"
"@esbuild/linux-arm" "0.17.19"
"@esbuild/linux-arm64" "0.17.19"
"@esbuild/linux-ia32" "0.17.19"
"@esbuild/linux-loong64" "0.17.19"
"@esbuild/linux-mips64el" "0.17.19"
"@esbuild/linux-ppc64" "0.17.19"
"@esbuild/linux-riscv64" "0.17.19"
"@esbuild/linux-s390x" "0.17.19"
"@esbuild/linux-x64" "0.17.19"
"@esbuild/netbsd-x64" "0.17.19"
"@esbuild/openbsd-x64" "0.17.19"
"@esbuild/sunos-x64" "0.17.19"
"@esbuild/win32-arm64" "0.17.19"
"@esbuild/win32-ia32" "0.17.19"
"@esbuild/win32-x64" "0.17.19"
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-scope@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz"
integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
version "3.4.1"
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz"
integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@^8.44.0:
version "8.44.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz"
integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.4.0"
"@eslint/eslintrc" "^2.1.0"
"@eslint/js" "8.44.0"
"@humanwhocodes/config-array" "^0.11.10"
"@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.3.2"
doctrine "^3.0.0"
escape-string-regexp "^4.0.0"
eslint-scope "^7.2.0"
eslint-visitor-keys "^3.4.1"
espree "^9.6.0"
esquery "^1.4.2"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1"
find-up "^5.0.0"
glob-parent "^6.0.2"
globals "^13.19.0"
graphemer "^1.4.0"
ignore "^5.2.0"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
is-path-inside "^3.0.3"
js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
lodash.merge "^4.6.2"
minimatch "^3.1.2"
natural-compare "^1.4.0"
optionator "^0.9.3"
strip-ansi "^6.0.1"
strip-json-comments "^3.1.0"
text-table "^0.2.0"
espree@^9.6.0:
version "9.6.0"
resolved "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz"
integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==
dependencies:
acorn "^8.9.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.1"
esquery@^1.4.2:
version "1.5.0"
resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz"
integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
dependencies:
estraverse "^5.1.0"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.1.0:
version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-glob@^3.2.9:
version "3.3.0"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz"
integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.2"
merge2 "^1.3.0"
micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fastq@^1.6.0:
version "1.15.0"
resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
dependencies:
reusify "^1.0.4"
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
dependencies:
flat-cache "^3.0.4"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
dependencies:
locate-path "^6.0.0"
path-exists "^4.0.0"
flat-cache@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
dependencies:
flatted "^3.1.0"
rimraf "^3.0.2"
flatted@^3.1.0:
version "3.2.7"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
is-glob "^4.0.3"
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^13.19.0:
version "13.20.0"
resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz"
integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
dependencies:
type-fest "^0.20.2"
globby@^11.1.0:
version "11.1.0"
resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
fast-glob "^3.2.9"
ignore "^5.2.0"
merge2 "^1.4.1"
slash "^3.0.0"
grapheme-splitter@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz"
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
graphemer@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
ignore@^5.2.0:
version "5.2.4"
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-path-inside@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
dependencies:
prelude-ls "^1.2.1"
type-check "~0.4.0"
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
dependencies:
p-locate "^5.0.0"
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
dependencies:
braces "^3.0.2"
picomatch "^2.3.1"
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
natural-compare-lite@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz"
integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz"
integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==
dependencies:
"@aashutoshrathi/word-wrap" "^1.2.3"
deep-is "^0.1.3"
fast-levenshtein "^2.0.6"
levn "^0.4.1"
prelude-ls "^1.2.1"
type-check "^0.4.0"
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
yocto-queue "^0.1.0"
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz"
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
dependencies:
p-limit "^3.0.2"
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
dependencies:
callsites "^3.0.0"
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
punycode@^2.1.0:
version "2.3.0"
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
queue-microtask "^1.2.2"
semver@^7.3.7:
version "7.5.3"
resolved "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz"
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
dependencies:
lru-cache "^6.0.0"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
dependencies:
prelude-ls "^1.2.1"
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
typescript@^5.1.6, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta":
version "5.1.6"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

View File

@@ -0,0 +1,25 @@
/* eslint-env node */
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
root: true,
"rules": {
// enable additional rules
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
// override configuration set by extending "eslint:recommended"
"no-empty": "warn",
"no-cond-assign": ["error", "always"],
// disable rules from base configurations
"for-direction": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/ban-ts-comment": "off"
}
};

View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,21 @@
# asusctl
Requires `asusd` to be installed and running.
## build and install
```
npm install
npm run build && gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
npm run build && gnome-extensions enable asusctl-gnome@asus-linux.org.zip
```
You will need to restart Gnome after installing or updating
## development
```
npm run build
gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
MUTTER_DEBUG_DUMMY_MODE_SPECS=1366x768 dbus-run-session -- gnome-shell --nested --wayland
```

View File

@@ -0,0 +1,65 @@
const { build } = require("esbuild");
const fs = require("fs");
const path = require("path");
var exec = require('child_process').exec;
const AdmZip = require("adm-zip");
const metadata = require("./src/metadata.json");
build({
entryPoints: ['src/extension.ts'],
outdir: 'dist',
bundle: true,
// Do not remove the functions `enable()`, `disable()` and `init()`
treeShaking: false,
// firefox60 // Since GJS 1.53.90
// firefox68 // Since GJS 1.63.90
// firefox78 // Since GJS 1.65.90
// firefox91 // Since GJS 1.71.1
// firefox102 // Since GJS 1.73.2
target: "firefox102",
platform: "node",
// platform: "neutral",
// mainFields: ['main'],
// conditions: ['require', 'default'],
format: 'esm',
external: ['gi://*', 'resource:///*', 'system', 'gettext', 'cairo'],
}).then(() => {
const metaSrc = path.resolve(__dirname, "src/metadata.json");
const metaDist = path.resolve(__dirname, "dist/metadata.json");
const schemaSrc = path.resolve(__dirname, "schemas");
const schemaDist = path.resolve(__dirname, "dist/schemas");
const dbusXmlSrc = path.resolve(__dirname, "../../bindings/dbus-xml");
const dbusXmlDist = path.resolve(__dirname, "dist/resources/dbus");
const zipFilename = `${metadata.uuid}.zip`;
const zipDist = path.resolve(__dirname, zipFilename);
exec('glib-compile-schemas schemas/',
(error, stdout, stderr) => {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
});
fs.copyFileSync(metaSrc, metaDist);
fs.cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
fs.cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
const zip = new AdmZip();
zip.addLocalFolder(path.resolve(__dirname, "dist"));
zip.writeZip(zipDist);
console.log(`Build complete. Zip file: ${zipFilename}\n`);
console.log(`Install with: gnome-extensions install ${zipFilename}`)
console.log(`Update with: gnome-extensions install ${zipFilename} --force`)
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`)
});

View File

@@ -0,0 +1,51 @@
#!/bin/bash
## Script to initialise dev-environment (types)
gv="44"
wd=${PWD}
# cleanup
rm -rf @types
# generate GJS from gir (this does not include the extensions)
echo "Generating GJS types from gir.."
npx ts-for-gir generate Shell-12 St-12 Gtk-4.0 \
-g /usr/share/gir-1.0 \
-g /usr/share/gnome-shell \
-g /usr/share/gnome-shell/gir-1.0 \
-g /usr/lib64/mutter-12 \
-t esm -o @types/Gjs
# get latest js (44) in this case and create the types for it
echo "Generating GJS Extension (Gex) types from extension source.."
mkdir -p ./_tmp/
cd ./_tmp
wget -q -O gnome-shell-js-${gv}.tar.gz https://gitlab.gnome.org/GNOME/gnome-shell/-/archive/gnome-${gv}/gnome-shell-gnome-${gv}.tar.gz?path=js
tar xf gnome-shell-js-${gv}.tar.gz
cd gnome-shell-gnome-${gv}-js
cat >tsconfig.json <<EOL
{
"include": ["js/ui/*"],
"exclude": [
"js/ui/shellDBus.js",
"node_modules",
"**/node_modules/*"
],
"compilerOptions": {
"allowJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "gex-types",
"declarationMap": true,
"lib": ["es2019"]
}
}
EOL
npx tsc
cd ${wd}
mv ./_tmp/gnome-shell-gnome-${gv}-js/gex-types @types/Gex
# rm -rf ./_tmp/
echo "done."
exit 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
{
"name": "asusctl-gnome",
"version": "4.7.0",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"main": "dist/extension.js",
"scripts": {
"clear": "rm -rf dist",
"build:app": "node esbuild.js",
"build": "yarn run clear && yarn run build:app",
"validate": "tsc --noEmit"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"adm-zip": "^0.5.10",
"esbuild": "^0.17.19",
"eslint": "^8.44.0",
"typescript": "^5.1.6"
},
"repository": {
"type": "git",
"url": "git+ssh://git@gitlab.com/asus-linux/asusctl.git"
},
"keywords": [
"gnome-shell",
"extension",
"asusctl",
"asus",
"rog",
"gnome",
"gjs",
"typescript"
],
"author": "Armas Spann, Marco Laux, Luke Jones",
"license": "MPL-2",
"bugs": {
"url": "https://gitlab.com/asus-linux/asusctl/issues"
},
"homepage": "https://gitlab.com/asus-linux/asusctl/desktop-extensions/gnome#readme"
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="AsusctlGnomeExtension">
<schema id="org.gnome.shell.extensions.asusctl-gnome" path="/org/gnome/shell/extensions/asusctl-gnome/" >
<key type="b" name="mini-led-enabled">
<default>false</default>
</key>
<key type="b" name="panel-od-enabled">
<default>false</default>
</key>
<key type="b" name="anime-power">
<default>false</default>
</key>
<key name="charge-level" type="u">
<range min="20" max="100"/>
<default>100</default>
</key>
<key type="s" name="primary-quickmenu-toggle">
<default>"mini-led"</default>
</key>
</schema>
</schemalist>

View File

@@ -0,0 +1 @@
../../../bindings/ts

View File

@@ -0,0 +1,117 @@
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
import { AnimeDbus } from "./modules/dbus/animatrix";
import { Power } from "./modules/dbus/power";
import { Supported } from "./modules/dbus/supported";
import { Platform } from "./modules/dbus/platform";
import { QuickPanelOd } from "./modules/quick_toggles/panel_od";
import { IndicateMiniLed } from "./modules/indicators/mini_led";
import { QuickMiniLed } from "./modules/quick_toggles/mini_led";
import { SliderChargeLevel } from "./modules/sliders/charge";
import { QuickAnimePower } from "./modules/quick_toggles/anime_power";
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
import { AuraDbus } from "./modules/dbus/aura";
import { AuraMenuToggle } from "./modules/quick_menus/aura";
export var extension;
export default class AsusExtension extends Extension {
private _indicateMiniLed: typeof IndicateMiniLed;
private _quickMiniLed: typeof QuickMiniLed;
private _quickPanelOd: typeof QuickPanelOd;
private _quickAnimePower: typeof QuickAnimePower;
private _featureMenuToggle: typeof FeatureMenuToggle;
private _auraModeMenuToggle: typeof AuraMenuToggle;
private _sliderCharge: typeof SliderChargeLevel;
public dbus_supported: Supported = new Supported;
public dbus_power: Power = new Power;
public dbus_aura: AuraDbus = new AuraDbus;
public dbus_anime: AnimeDbus = new AnimeDbus;
public dbus_platform: Platform = new Platform;
public extensionPath: any = null;
settings() {
return this._settings;
}
async enable() {
this._settings = this.getSettings();
this.extensionPath = this.path;
extension = this;
this._indicateMiniLed = null;
this._quickMiniLed = null;
this._quickPanelOd = null;
this._quickAnimePower = null;
this._sliderCharge = null;
await this.dbus_supported.start();
await this.dbus_aura.start();
await this.dbus_platform.start();
await this.dbus_power.start();
await this.dbus_anime.start();
if (this._featureMenuToggle == null) {
this._featureMenuToggle = new FeatureMenuToggle(this.dbus_supported, this.dbus_platform, this.dbus_anime);
}
if (this._auraModeMenuToggle == null) {
this._auraModeMenuToggle = new AuraMenuToggle(this.dbus_aura);
}
if (this.dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
// if (this._quickMiniLed == null) {
// this._quickMiniLed = new QuickMiniLed(this.dbus_platform);
// this.dbus_platform.notifyMiniLedSubscribers.push(this._quickMiniLed);
// }
if (this._indicateMiniLed == null) {
this._indicateMiniLed = new IndicateMiniLed(this.dbus_platform);
}
}
// if (this.dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
// if (this._quickPanelOd == null) {
// this._quickPanelOd = new QuickPanelOd(this.dbus_platform);
// this.dbus_platform.notifyPanelOdSubscribers.push(this._quickPanelOd);
// }
// }
// if (this.dbus_supported.supported.anime_ctrl) {
// if (this._quickAnimePower == null) {
// this._quickAnimePower = new QuickAnimePower(this._dbus_anime);
// }
// }
if (this.dbus_supported.supported.charge_ctrl.charge_level_set) {
if (this._sliderCharge == null) {
this._sliderCharge = new SliderChargeLevel(this.dbus_power);
}
}
}
disable() {
if (this._indicateMiniLed != null) {
this._indicateMiniLed.destroy();
this._indicateMiniLed = null;
}
if (this._quickMiniLed != null) {
this._quickMiniLed.destroy();
this._quickMiniLed = null;
}
if (this._quickPanelOd != null) {
this._quickPanelOd.destroy();
this._quickPanelOd = null;
}
if (this._quickAnimePower != null) {
this._quickAnimePower.destroy();
this._quickAnimePower = null;
}
if (this._sliderCharge != null) {
this._sliderCharge.destroy();
this._sliderCharge = null;
}
this.dbus_power.stop();
this.dbus_platform.stop();
// this.dbus_anime.stop();
this.dbus_aura.stop();
this.dbus_supported.stop();
}
}

View File

@@ -0,0 +1,11 @@
{
"name": "asusctl-gnome",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"uuid": "asusctl-gnome@asus-linux.org",
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
"version": "4.3.2",
"shell-version": [
"43", "44", "45"
]
}

View File

@@ -0,0 +1,119 @@
import { DbusBase } from "./base";
import { DeviceState, AnimBooting, Brightness, AnimAwake, AnimSleeping, AnimShutdown } from "../../bindings/anime";
export class AnimeDbus extends DbusBase {
deviceState: DeviceState = {
display_enabled: false,
display_brightness: Brightness.Med,
builtin_anims_enabled: false,
builtin_anims: {
boot: AnimBooting.GlitchConstruction,
awake: AnimAwake.BinaryBannerScroll,
sleep: AnimSleeping.BannerSwipe,
shutdown: AnimShutdown.GlitchOut
},
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAnimeStateSubscribers: any[] = [];
constructor() {
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
}
public setEnableDisplay(state: boolean | null) {
if (this.isRunning()) {
try {
// if null, toggle the current state
state = (state == null ? !this.deviceState.display_enabled : state);
if (this.deviceState.display_enabled !== state) {
this.deviceState.display_enabled = state;
}
return this.dbus_proxy.SetEnableDisplaySync(state);
} catch (e) {
//@ts-ignore
log("AniMe DBus set power failed!", e);
}
}
}
public setPowersaveAnim(state: boolean | null) {
if (this.isRunning()) {
try {
// if null, toggle the current state
state = (state == null ? !this.deviceState.builtin_anims_enabled : state);
if (this.deviceState.builtin_anims_enabled !== state) {
this.deviceState.builtin_anims_enabled = state;
}
return this.dbus_proxy.SetEnableBuiltinsSync(state);
} catch (e) {
//@ts-ignore
log("AniMe DBus set builtins failed!", e);
}
}
}
public setBrightness(brightness: Brightness) {
if (this.isRunning()) {
try {
if (this.deviceState.display_brightness !== brightness) {
this.deviceState.display_brightness = brightness;
}
return this.dbus_proxy.SetBrightnessSync(brightness);
} catch (e) {
//@ts-ignore
log("AniMe DBus set brightness failed!", e);
}
}
}
_parseData(data: any) {
if (data.length > 0) {
this.deviceState.display_enabled = data[0];
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
this.deviceState.builtin_anims_enabled = data[2];
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][2] as AnimShutdown];
}
}
public getDeviceState() {
if (this.isRunning()) {
try {
// janky shit going on with DeviceStateSync
this._parseData(this.dbus_proxy.DeviceStateSync());
} catch (e) {
//@ts-ignore
log("Failed to fetch DeviceState!", e);
}
}
return this.deviceState;
}
async start() {
await super.start();
this.getDeviceState();
this.dbus_proxy.connectSignal(
"NotifyDeviceState",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(proxy: any = null, name: string, data: string) => {
if (proxy) {
// idiot xml parsing mneans the get is not nested while this is
this._parseData(data[0]);
this.notifyAnimeStateSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,284 @@
import { AuraDevRog1, AuraDevTuf, AuraDevice, AuraEffect, AuraModeNum, AuraPower, AuraPowerDev, AuraZone, Direction, PowerZones, Speed } from "../../bindings/aura";
import { DbusBase } from "./base";
export class AuraDbus extends DbusBase {
public device: AuraDevice = AuraDevice.Unknown;
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map;
public leds_powered: AuraPowerDev = {
tuf: [],
old_rog: [],
rog: {
keyboard: {
zone: PowerZones.Keyboard,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
logo: {
zone: PowerZones.Logo,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
lightbar: {
zone: PowerZones.Lightbar,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
lid: {
zone: PowerZones.Lid,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
rear_glow: {
zone: PowerZones.RearGlow,
boot: false,
awake: false,
sleep: false,
shutdown: false
},
}
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAuraModeSubscribers: any[] = [];
public notifyAuraPowerSubscribers: any[] = [];
constructor() {
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
}
public getDevice() {
if (this.isRunning()) {
try {
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
//@ts-ignore
log("LED device: " + this.device);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parsePowerStates(data: any[]) {
const power: AuraPowerDev = this.leds_powered;
power.tuf = data[0].map((value: string) => {
return AuraDevTuf[value as AuraDevTuf];
});
power.old_rog = data[1].map((value: string) => {
return AuraDevRog1[value as AuraDevRog1];
});
power.rog = {
keyboard: {
zone: PowerZones[data[2][0][0] as PowerZones],
boot: data[2][0][1],
awake: data[2][0][2],
sleep: data[2][0][3],
shutdown: data[2][0][4]
},
logo: {
zone: PowerZones[data[2][1][0] as PowerZones],
boot: data[2][1][1],
awake: data[2][1][2],
sleep: data[2][1][3],
shutdown: data[2][1][4]
},
lightbar: {
zone: PowerZones[data[2][2][0] as PowerZones],
boot: data[2][2][1],
awake: data[2][2][2],
sleep: data[2][2][3],
shutdown: data[2][2][4]
},
lid: {
zone: PowerZones[data[2][3][0] as PowerZones],
boot: data[2][3][1],
awake: data[2][3][2],
sleep: data[2][3][3],
shutdown: data[2][3][4]
},
rear_glow: {
zone: PowerZones[data[2][4][0] as PowerZones],
boot: data[2][4][1],
awake: data[2][4][2],
sleep: data[2][4][3],
shutdown: data[2][4][4]
}
};
return power;
}
public getLedPower() {
if (this.isRunning()) {
try {
const data = this.dbus_proxy.LedPowerSync();
this.leds_powered = this._parsePowerStates(data);
//@ts-ignore
log("LED power tuf: " + this.leds_powered.tuf);
//@ts-ignore
log("LED power x1866: " + this.leds_powered.old_rog);
//@ts-ignore
log("LED power x19b6: " + this.leds_powered.rog);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public getLedMode() {
if (this.isRunning()) {
try {
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
//@ts-ignore
log("Current LED mode:", this.current_aura_mode);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public setLedMode(mode: AuraEffect) {
if (this.isRunning()) {
try {
this.dbus_proxy.SetLedModeSync([
mode.mode,
mode.zone,
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
mode.speed,
mode.direction]);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parseAuraEffect(data: any[]) {
const aura: AuraEffect = {
mode: AuraModeNum[data[0] as AuraModeNum],
zone: AuraZone[data[1] as AuraZone],
colour1: {
r: parseInt(data[2][0]),
g: parseInt(data[2][1]),
b: parseInt(data[2][2]),
},
colour2: {
r: parseInt(data[3][0]),
g: parseInt(data[3][1]),
b: parseInt(data[3][2]),
},
speed: Speed[data[4] as Speed],
direction: Direction[data[5] as Direction],
};
return aura;
}
// Return a list of the available modes, and the current settings for each
public getLedModes() {
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
if (this.isRunning()) {
try {
const _data = this.dbus_proxy.LedModesSync();
for (const key in _data[0]) {
const data = _data[0][key];
const aura: AuraEffect = this._parseAuraEffect(data);
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
}
for (const [key, value] of this.aura_modes) {
//@ts-ignore
log(key, value.zone, value.colour1.r, value.speed, value.direction);
}
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
async start() {
try {
await super.start();
this.getDevice();
this.getLedPower();
this.getLedMode();
this.getLedModes();
//@ts-ignore
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
this.dbus_proxy.connectSignal(
"NotifyLed",
(proxy: any = null, name: string, data: any) => {
if (proxy) {
const aura: AuraEffect = this._parseAuraEffect(data[0]);
this.current_aura_mode = aura.mode;
this.aura_modes.set(aura.mode, aura);
//@ts-ignore
log("LED data has changed to ", aura.mode, aura.zone, aura.colour1.r, aura.speed, aura.direction);
this.notifyAuraModeSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.dbus_proxy.connectSignal(
"NotifyPowerStates",
(proxy: any = null, name: string, data: any) => {
if (proxy) {
const power: AuraPowerDev = this._parsePowerStates(data[0]);
this.leds_powered = power;
switch (this.device) {
case AuraDevice.Tuf:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.tuf);
break;
case AuraDevice.X1854:
case AuraDevice.X1869:
case AuraDevice.X18c6:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.old_rog);
break;
case AuraDevice.X19b6:
case AuraDevice.X1a30:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
break;
default:
break;
}
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
this.notifyAuraPowerSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
} catch (e) {
//@ts-ignore
log("Supported DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

View File

@@ -0,0 +1,49 @@
import * as Resources from "../resources";
import Gio from 'gi://Gio';
export class DbusBase {
dbus_proxy: any = null; // type: Gio.DbusProxy
connected = false;
xml_resource = "";
dbus_path = "";
constructor(resource: string, dbus_path: string) {
this.xml_resource = resource;
this.dbus_path = dbus_path;
}
async start() {
//@ts-ignore
log(`Starting ${this.dbus_path} dbus module`);
try {
const xml = Resources.File.DBus(this.xml_resource);
this.dbus_proxy = new Gio.DBusProxy.makeProxyWrapper(xml)(
Gio.DBus.system,
"org.asuslinux.Daemon",
this.dbus_path,
);
this.connected = true;
//@ts-ignore
log(`${this.dbus_path} client started successfully.`);
} catch (e) {
//@ts-ignore
logError(`${this.xml_resource} dbus init failed!`, e);
}
}
async stop() {
//@ts-ignore
log(`Stopping ${this.xml_resource} dbus module`);
if (this.connected) {
this.dbus_proxy.destroy();
this.connected = false;
this.dbus_proxy = null;
}
}
isRunning(): boolean {
return this.connected;
}
}

View File

@@ -0,0 +1,202 @@
import * as bios from "../../bindings/platform";
import { DbusBase } from "./base";
// TODO: add callbacks for notifications
export class Platform extends DbusBase {
bios: bios.RogBiosSupportedFunctions = {
post_sound: false,
gpu_mux: false,
panel_overdrive: false,
dgpu_disable: false,
egpu_enable: false,
mini_led_mode: false
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyPanelOdSubscribers: any[] = [];
public notifyPostBootSoundSubscribers: any[] = [];
public notifyMiniLedSubscribers: any[] = [];
public notifyGpuMuxSubscribers: any[] = [];
constructor() {
super("org-asuslinux-platform-4", "/org/asuslinux/Platform");
}
public getPostBootSound() {
if (this.isRunning()) {
try {
this.bios.post_sound = this.dbus_proxy.PostBootSoundSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get POST Boot Sound state!", e);
}
}
return this.bios.post_sound;
}
public setPostBootSound(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.post_sound) {
this.bios.post_sound = state;
}
return this.dbus_proxy.SetPostBootSoundSync(state);
} catch (e) {
//@ts-ignore
log("Platform DBus set Post Boot Sound failed!", e);
}
}
}
public getGpuMuxMode() {
if (this.isRunning()) {
try {
this.bios.gpu_mux = this.dbus_proxy.GpuMuxModeSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get MUX state!", e);
}
}
return this.bios.gpu_mux;
}
public setGpuMuxMode(state: boolean) {
if (this.isRunning()) {
try {
if (!state !== this.bios.gpu_mux) {
this.bios.gpu_mux = !state;
}
return this.dbus_proxy.SetGpuMuxModeSync(!state);
} catch (e) {
//@ts-ignore
log("Switching the MUX failed!", e);
}
}
}
public getPanelOd() {
if (this.isRunning()) {
try {
this.bios.panel_overdrive = this.dbus_proxy.PanelOdSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get Overdrive state!", e);
}
}
return this.bios.panel_overdrive;
}
public setPanelOd(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.panel_overdrive) {
this.bios.panel_overdrive = state;
}
return this.dbus_proxy.SetPanelOdSync(state);
} catch (e) {
//@ts-ignore
log("Overdrive DBus set overdrive state failed!", e);
}
}
}
public getMiniLedMode() {
if (this.isRunning()) {
try {
this.bios.mini_led_mode = this.dbus_proxy.MiniLedModeSync() == "true" ? true : false;
} catch (e) {
//@ts-ignore
log("Failed to get Overdrive state!", e);
}
}
return this.bios.mini_led_mode;
}
public setMiniLedMode(state: boolean) {
if (this.isRunning()) {
try {
if (state !== this.bios.mini_led_mode) {
this.bios.mini_led_mode = state;
}
return this.dbus_proxy.SetMiniLedModeSync(state);
} catch (e) {
//@ts-ignore
log("setMiniLedMode failed!", e);
}
}
}
async start() {
try {
await super.start();
this.getPostBootSound();
this.dbus_proxy.connectSignal(
"NotifyPostBootSound",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`PostBootSound changed to ${data}`);
this.notifyPostBootSoundSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getPanelOd();
this.dbus_proxy.connectSignal(
"NotifyPanelOd",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`NotifyPanelOd has changed to ${data}.`);
this.notifyPanelOdSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getMiniLedMode();
this.dbus_proxy.connectSignal(
"NotifyMiniLedMode",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`MiniLedMode has changed to ${data}.`);
this.notifyMiniLedSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
this.getGpuMuxMode();
this.dbus_proxy.connectSignal(
"NotifyGpuMuxMode",
(proxy: any = null, _name: string, data: boolean) => {
if (proxy) {
//@ts-ignore
log(`MUX has changed to ${data}.`);
this.notifyGpuMuxSubscribers.forEach(sub => {
sub.sync();
});
}
}
);
} catch (e) {
//@ts-ignore
log("Platform DBus init failed!", e);
}
}
async stop() {
await super.stop();
this.bios.post_sound = false;
this.bios.panel_overdrive = false;
this.bios.mini_led_mode = false;
this.bios.gpu_mux = false;
}
}

View File

@@ -0,0 +1,99 @@
import { DbusBase } from "./base";
// function getMethods(obj: { [x: string]: { toString: () => string; }; }) {
// var result = [];
// for (var id in obj) {
// try {
// if (typeof(obj[id]) == "function") {
// result.push(id + ": " + obj[id].toString());
// }
// } catch (err) {
// result.push(id + ": inaccessible");
// }
// }
// return result;
// }
export class Power extends DbusBase {
chargeLimit = 100;
mainsOnline = false;
constructor() {
super("org-asuslinux-power-4", "/org/asuslinux/Power");
}
public getChargingLimit() {
if (this.isRunning()) {
try {
this.chargeLimit = this.dbus_proxy.ChargeControlEndThresholdSync();
} catch (e) {
//@ts-ignore
log("Failed to fetch Charging Limit!", e);
}
}
return this.chargeLimit;
}
public setChargingLimit(limit: number) {
if (this.isRunning()) {
try {
if (limit > 0 && this.chargeLimit !== limit) {
// update state
this.chargeLimit = limit;
}
return this.dbus_proxy.SetChargeControlEndThresholdSync(limit);
} catch (e) {
//@ts-ignore
log("Profile DBus set power profile failed!", e);
}
}
}
public getMainsOnline() {
if (this.isRunning()) {
try {
this.mainsOnline = this.dbus_proxy.MainsOnlineSync();
} catch (e) {
//@ts-ignore
log("Failed to fetch MainsLonline!", e);
}
}
return this.mainsOnline;
}
async start() {
try {
await super.start();
this.getChargingLimit();
this.dbus_proxy.connectSignal(
"NotifyChargeControlEndThreshold",
(proxy: any = null, name: string, data: string) => {
if (proxy) {
//@ts-ignore
log(`Charging Limit has changed to ${data}% (${name}).`);
this.chargeLimit = parseInt(data);
}
}
);
this.dbus_proxy.connectSignal(
"NotifyMainsOnline",
(proxy: any = null, name: string, data: string) => {
if (proxy) {
//@ts-ignore
log(`NotifyMainsOnline has changed to ${data}% (${name}).`);
this.mainsOnline = parseInt(data) == 1 ? true : false;
}
}
);
} catch (e) {
//@ts-ignore
log("Charging Limit DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

Some files were not shown because too many files have changed in this diff Show More