mirror of
https://github.com/OpenActionAPI/rust-elgato-streamdeck.git
synced 2026-10-28 09:44:56 +00:00
Support Ajazz AKP153 (#6)
* Apply cargo fmt * Add simple example * Support Ajazz AKP153 * Apply requested changes.
This commit is contained in:
1 parent
20350cc6e0
commit
910996dba3
15 files changed
+1271
-331
No files matched your search
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.rs]
|
||||
indent_size = 4
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
**/target/
|
||||
|
||||
.idea/
|
||||
|
||||
|
||||
+5
-1
@@ -7,6 +7,7 @@ SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0080", MODE="0660",
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0090", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0086", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0084", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="5548", ATTR{idProduct}=="6674", MODE="0660", GROUP="plugdev"
|
||||
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE="0660", GROUP="plugdev"
|
||||
@@ -17,6 +18,7 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE="0660"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="5548", ATTRS{idProduct}=="6674", MODE="0660", GROUP="plugdev"
|
||||
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0060", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="006d", MODE="0660", GROUP="plugdev"
|
||||
@@ -27,6 +29,7 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0090", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0086", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0084", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="5548", ATTR{idProduct}=="6674", MODE="0660", GROUP="plugdev"
|
||||
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE="0660", GROUP="plugdev"
|
||||
@@ -36,4 +39,5 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="5548", ATTRS{idProduct}=="6674", MODE="0660", GROUP="plugdev"
|
||||
+11
-2
@@ -11,7 +11,10 @@ license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
hidapi = { version = "2.4", default-features = false }
|
||||
image = { version = "0.24.6", default-features = false, features = ["bmp", "jpeg"] }
|
||||
image = { version = "0.24.6", default-features = false, features = [
|
||||
"bmp",
|
||||
"jpeg",
|
||||
] }
|
||||
tokio = { version = "1", optional = true }
|
||||
async-recursion = { version = "1.0.2", optional = true }
|
||||
|
||||
@@ -19,7 +22,13 @@ async-recursion = { version = "1.0.2", optional = true }
|
||||
serial_test = "2.0.0"
|
||||
|
||||
[features]
|
||||
async = ["tokio", "tokio/sync", "tokio/rt-multi-thread", "tokio/time", "async-recursion"]
|
||||
async = [
|
||||
"tokio",
|
||||
"tokio/sync",
|
||||
"tokio/rt-multi-thread",
|
||||
"tokio/time",
|
||||
"async-recursion",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
@@ -49,6 +49,11 @@ let image = open("no-place-like-localhost.jpg").unwrap();
|
||||
|
||||
// Write it to the device
|
||||
device.set_button_image(7, image).unwrap();
|
||||
|
||||
// Flush
|
||||
if device.updated {
|
||||
device.flush().unwrap();
|
||||
}
|
||||
```
|
||||
|
||||
## Status
|
||||
@@ -69,4 +74,6 @@ But as it stands, this library should support following devices:
|
||||
- Stream Deck Mini Mk2
|
||||
- Stream Deck Mk2
|
||||
- Stream Deck Pedal
|
||||
- Stream Deck Plus (thanks to [node-elgato-stream-deck](https://github.com/Julusian/node-elgato-stream-deck))
|
||||
- Stream Deck Plus (thanks to [node-elgato-stream-deck](https://github.com/Julusian/node-elgato-stream-deck))
|
||||
|
||||
- Ajazz AKP153
|
||||
Generated
+516
@@ -0,0 +1,516 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "elgato-streamdeck"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"hidapi",
|
||||
"image",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hidapi"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e58251020fe88fe0dae5ebcc1be92b4995214af84725b375d08354d0311c23c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"jpeg-decoder",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"elgato-streamdeck",
|
||||
"hidapi",
|
||||
"image",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "simple"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
hidapi = { version = "2.4", default-features = false }
|
||||
image = { version = "0.24.6", default-features = false, features = [
|
||||
"bmp",
|
||||
"jpeg",
|
||||
] }
|
||||
tokio = { version = "1", optional = false, features = ["full"] }
|
||||
async-recursion = { version = "1.0.2", optional = false }
|
||||
elgato-streamdeck = { path = "../../" }
|
||||
File renamed without changes.
@@ -0,0 +1,81 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use elgato_streamdeck::{list_devices, new_hidapi, DeviceStateUpdate, StreamDeck};
|
||||
use image::open;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Create instance of HidApi
|
||||
match new_hidapi() {
|
||||
Ok(hid) => {
|
||||
// Refresh device list
|
||||
for (kind, serial) in list_devices(&hid) {
|
||||
println!("{:?} {} {}", kind, serial, kind.product_id());
|
||||
|
||||
// Connect to the device
|
||||
let mut device = StreamDeck::connect(&hid, kind, &serial).expect("Failed to connect");
|
||||
// Print out some info from the device
|
||||
println!("Connected to '{}' with version '{}'", device.serial_number().unwrap(), device.firmware_version().unwrap());
|
||||
|
||||
device.set_brightness(50).unwrap();
|
||||
device.clear_button_image(0xff).unwrap();
|
||||
// Use image-rs to load an image
|
||||
let image = open("no-place-like-localhost.jpg").unwrap();
|
||||
|
||||
// device.set_logo_image(image.clone()).unwrap();
|
||||
|
||||
device.set_brightness(50).unwrap();
|
||||
device.clear_button_image(0xff).unwrap();
|
||||
|
||||
println!("Key count: {}", kind.key_count());
|
||||
// Write it to the device
|
||||
for i in 0..kind.key_count() as u8 {
|
||||
device.set_button_image(i, image.clone()).unwrap();
|
||||
}
|
||||
|
||||
// Flush
|
||||
if device.is_updated() {
|
||||
device.flush().unwrap();
|
||||
}
|
||||
|
||||
let device = Arc::new(device);
|
||||
{
|
||||
let reader = device.get_reader();
|
||||
|
||||
let updates = match reader.read(Some(Duration::from_secs_f64(100.0))) {
|
||||
Ok(updates) => updates,
|
||||
Err(_) => break,
|
||||
};
|
||||
for update in updates {
|
||||
match update {
|
||||
DeviceStateUpdate::ButtonDown(key) => {
|
||||
println!("Button {} down", key);
|
||||
}
|
||||
DeviceStateUpdate::ButtonUp(key) => {
|
||||
println!("Button {} up", key);
|
||||
}
|
||||
DeviceStateUpdate::EncoderTwist(dial, ticks) => {
|
||||
println!("Dial {} twisted by {}", dial, ticks);
|
||||
}
|
||||
DeviceStateUpdate::EncoderDown(dial) => {
|
||||
println!("Dial {} down", dial);
|
||||
}
|
||||
DeviceStateUpdate::EncoderUp(dial) => {
|
||||
println!("Dial {} up", dial);
|
||||
}
|
||||
_ => {
|
||||
println!("Unknown update");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop(reader);
|
||||
}
|
||||
|
||||
device.shutdown().unwrap();
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Failed to create HidApi instance: {}", e),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
edition = "2021"
|
||||
hard_tabs = false
|
||||
max_width = 200
|
||||
newline_style = "Unix"
|
||||
reorder_imports = false
|
||||
reorder_modules = false
|
||||
+36
-50
@@ -16,9 +16,7 @@ use crate::images::{convert_image_async, ImageRect};
|
||||
|
||||
/// Actually refreshes the device list, can be safely ran inside [multi_thread](tokio::runtime::Builder::new_multi_thread) runtime
|
||||
pub fn refresh_device_list_async(hidapi: &mut HidApi) -> HidResult<()> {
|
||||
block_in_place(move || {
|
||||
hidapi.refresh_devices()
|
||||
})
|
||||
block_in_place(move || hidapi.refresh_devices())
|
||||
}
|
||||
|
||||
/// Returns a list of devices as (Kind, Serial Number) that could be found using HidApi,
|
||||
@@ -26,9 +24,7 @@ pub fn refresh_device_list_async(hidapi: &mut HidApi) -> HidResult<()> {
|
||||
///
|
||||
/// **WARNING:** To refresh the list, use [refresh_device_list]
|
||||
pub fn list_devices_async(hidapi: &HidApi) -> Vec<(Kind, String)> {
|
||||
block_in_place(move || {
|
||||
list_devices(&hidapi)
|
||||
})
|
||||
block_in_place(move || list_devices(&hidapi))
|
||||
}
|
||||
|
||||
/// Stream Deck interface suitable to be used in async, uses [block_in_place](block_in_place)
|
||||
@@ -36,7 +32,7 @@ pub fn list_devices_async(hidapi: &HidApi) -> Vec<(Kind, String)> {
|
||||
#[derive(Clone)]
|
||||
pub struct AsyncStreamDeck {
|
||||
kind: Kind,
|
||||
device: Arc<Mutex<StreamDeck>>
|
||||
device: Arc<Mutex<StreamDeck>>,
|
||||
}
|
||||
|
||||
/// Static functions of the struct
|
||||
@@ -47,7 +43,7 @@ impl AsyncStreamDeck {
|
||||
|
||||
Ok(AsyncStreamDeck {
|
||||
kind,
|
||||
device: Arc::new(Mutex::new(device))
|
||||
device: Arc::new(Mutex::new(device)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -63,36 +59,28 @@ impl AsyncStreamDeck {
|
||||
pub async fn manufacturer(&self) -> Result<String, StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.manufacturer()
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.manufacturer())?)
|
||||
}
|
||||
|
||||
/// Returns product string of the device
|
||||
pub async fn product(&self) -> Result<String, StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.product()
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.product())?)
|
||||
}
|
||||
|
||||
/// Returns serial number of the device
|
||||
pub async fn serial_number(&self) -> Result<String, StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.serial_number()
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.serial_number())?)
|
||||
}
|
||||
|
||||
/// Returns firmware version of the StreamDeck
|
||||
pub async fn firmware_version(&self) -> Result<String, StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.firmware_version()
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.firmware_version())?)
|
||||
}
|
||||
|
||||
/// Reads button states, awaits until there's data.
|
||||
@@ -101,9 +89,7 @@ impl AsyncStreamDeck {
|
||||
loop {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
let data = block_in_place(move || {
|
||||
lock.read_input(None)
|
||||
})?;
|
||||
let data = block_in_place(move || lock.read_input(None))?;
|
||||
|
||||
if !data.is_empty() {
|
||||
return Ok(data);
|
||||
@@ -120,7 +106,7 @@ impl AsyncStreamDeck {
|
||||
states: Mutex::new(DeviceState {
|
||||
buttons: vec![false; self.kind.key_count() as usize],
|
||||
encoders: vec![false; self.kind.encoder_count() as usize],
|
||||
})
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -128,36 +114,28 @@ impl AsyncStreamDeck {
|
||||
pub async fn reset(&self) -> Result<(), StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.reset()
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.reset())?)
|
||||
}
|
||||
|
||||
/// Sets brightness of the device, value range is 0 - 100
|
||||
pub async fn set_brightness(&self, percent: u8) -> Result<(), StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.set_brightness(percent)
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.set_brightness(percent))?)
|
||||
}
|
||||
|
||||
/// Writes image data to Stream Deck device, needs to accept Arc for image data since it runs a blocking thread under the hood
|
||||
pub async fn write_image(&self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.write_image(key, image_data)
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.write_image(key, image_data))?)
|
||||
}
|
||||
|
||||
/// Writes image data to Stream Deck device's lcd strip/screen, needs to accept Arc for image data since it runs a blocking thread under the hood
|
||||
pub async fn write_lcd(&self, x: u16, y: u16, rect: &ImageRect) -> Result<(), StreamDeckError> {
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.write_lcd(x, y, rect)
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.write_lcd(x, y, rect))?)
|
||||
}
|
||||
|
||||
/// Writes image data to Stream Deck device
|
||||
@@ -165,9 +143,10 @@ impl AsyncStreamDeck {
|
||||
let image = self.kind.blank_image();
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.write_image(key, &image)
|
||||
})?)
|
||||
match self.kind {
|
||||
Kind::Akp153 => Ok(block_in_place(move || lock.clear_button_image(key))?),
|
||||
_ => Ok(block_in_place(move || lock.write_image(key, &image))?),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets specified button's image
|
||||
@@ -176,16 +155,14 @@ impl AsyncStreamDeck {
|
||||
|
||||
let device = self.device.clone();
|
||||
let lock = device.lock().await;
|
||||
Ok(block_in_place(move || {
|
||||
lock.write_image(key, &image)
|
||||
})?)
|
||||
Ok(block_in_place(move || lock.write_image(key, &image))?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Button reader that keeps state of the Stream Deck and returns events instead of full states
|
||||
pub struct AsyncDeviceStateReader {
|
||||
device: AsyncStreamDeck,
|
||||
states: Mutex<DeviceState>
|
||||
states: Mutex<DeviceState>,
|
||||
}
|
||||
|
||||
impl AsyncDeviceStateReader {
|
||||
@@ -200,11 +177,21 @@ impl AsyncDeviceStateReader {
|
||||
match input {
|
||||
StreamDeckInput::ButtonStateChange(buttons) => {
|
||||
for (index, (their, mine)) in zip(buttons.iter(), my_states.buttons.iter()).enumerate() {
|
||||
if *their != *mine {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
} else {
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
match self.device.kind {
|
||||
Kind::Akp153 => {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if *their != *mine {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
} else {
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +236,6 @@ impl AsyncDeviceStateReader {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
drop(my_states);
|
||||
|
||||
if updates.is_empty() {
|
||||
@@ -258,4 +244,4 @@ impl AsyncDeviceStateReader {
|
||||
Ok(updates)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -22,7 +22,7 @@ pub fn convert_image(kind: Kind, image: DynamicImage) -> Result<Vec<u8>, ImageEr
|
||||
ImageRotation::Rot0 => image,
|
||||
ImageRotation::Rot90 => image.rotate90(),
|
||||
ImageRotation::Rot180 => image.rotate180(),
|
||||
ImageRotation::Rot270 => image.rotate270()
|
||||
ImageRotation::Rot270 => image.rotate270(),
|
||||
};
|
||||
|
||||
// Applying mirroring
|
||||
@@ -30,7 +30,7 @@ pub fn convert_image(kind: Kind, image: DynamicImage) -> Result<Vec<u8>, ImageEr
|
||||
ImageMirroring::None => image,
|
||||
ImageMirroring::X => image.fliph(),
|
||||
ImageMirroring::Y => image.flipv(),
|
||||
ImageMirroring::Both => image.fliph().flipv()
|
||||
ImageMirroring::Both => image.fliph().flipv(),
|
||||
};
|
||||
|
||||
let image_data = image.into_rgb8().to_vec();
|
||||
@@ -69,7 +69,7 @@ pub struct ImageRect {
|
||||
pub h: u16,
|
||||
|
||||
/// Data of the image row by row as RGB
|
||||
pub data: Vec<u8>
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl ImageRect {
|
||||
@@ -96,4 +96,4 @@ impl ImageRect {
|
||||
pub fn from_image_async(image: DynamicImage) -> Result<ImageRect, StreamDeckError> {
|
||||
Ok(tokio::task::block_in_place(move || ImageRect::from_image(image))?)
|
||||
}
|
||||
}
|
||||
}
|
||||
+137
-168
@@ -20,6 +20,12 @@ pub const PID_STREAMDECK_PEDAL: u16 = 0x0086;
|
||||
/// Product ID of Stream Deck Plus
|
||||
pub const PID_STREAMDECK_PLUS: u16 = 0x0084;
|
||||
|
||||
/// Vendor ID of Ajazz Stream Deck
|
||||
pub const AJAZZ_VENDOR_ID: u16 = 0x5548;
|
||||
|
||||
/// Product ID of Ajazz Stream Deck AK153
|
||||
pub const PID_AJAZZ_AKP153: u16 = 0x6674;
|
||||
|
||||
/// Enum describing kinds of Stream Decks out there
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub enum Kind {
|
||||
@@ -40,7 +46,9 @@ pub enum Kind {
|
||||
/// Stream Deck Pedal
|
||||
Pedal,
|
||||
/// Stream Deck Plus
|
||||
Plus
|
||||
Plus,
|
||||
/// Ajazz Stream Deck AK153
|
||||
Akp153,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
@@ -56,7 +64,8 @@ impl Kind {
|
||||
PID_STREAMDECK_MINI_MK2 => Some(Kind::MiniMk2),
|
||||
PID_STREAMDECK_PEDAL => Some(Kind::Pedal),
|
||||
PID_STREAMDECK_PLUS => Some(Kind::Plus),
|
||||
_ => None
|
||||
PID_AJAZZ_AKP153 => Some(Kind::Akp153),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,13 +80,25 @@ impl Kind {
|
||||
Kind::Mk2 => PID_STREAMDECK_MK2,
|
||||
Kind::MiniMk2 => PID_STREAMDECK_MINI_MK2,
|
||||
Kind::Pedal => PID_STREAMDECK_PEDAL,
|
||||
Kind::Plus => PID_STREAMDECK_PLUS
|
||||
Kind::Plus => PID_STREAMDECK_PLUS,
|
||||
Kind::Akp153 => PID_AJAZZ_AKP153,
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves Vendor ID used by Elgato hardware
|
||||
pub fn vendor_id(&self) -> u16 {
|
||||
ELGATO_VENDOR_ID
|
||||
match self {
|
||||
Kind::Original => ELGATO_VENDOR_ID,
|
||||
Kind::OriginalV2 => ELGATO_VENDOR_ID,
|
||||
Kind::Mini => ELGATO_VENDOR_ID,
|
||||
Kind::Xl => ELGATO_VENDOR_ID,
|
||||
Kind::XlV2 => ELGATO_VENDOR_ID,
|
||||
Kind::Mk2 => ELGATO_VENDOR_ID,
|
||||
Kind::MiniMk2 => ELGATO_VENDOR_ID,
|
||||
Kind::Pedal => ELGATO_VENDOR_ID,
|
||||
Kind::Plus => ELGATO_VENDOR_ID,
|
||||
Kind::Akp153 => AJAZZ_VENDOR_ID,
|
||||
}
|
||||
}
|
||||
|
||||
/// Amount of keys the Stream Deck kind has
|
||||
@@ -87,7 +108,8 @@ impl Kind {
|
||||
Kind::Mini | Kind::MiniMk2 => 6,
|
||||
Kind::Xl | Kind::XlV2 => 32,
|
||||
Kind::Pedal => 3,
|
||||
Kind::Plus => 8
|
||||
Kind::Plus => 8,
|
||||
Kind::Akp153 => 15 + 3,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +120,8 @@ impl Kind {
|
||||
Kind::Mini | Kind::MiniMk2 => 2,
|
||||
Kind::Xl | Kind::XlV2 => 4,
|
||||
Kind::Pedal => 1,
|
||||
Kind::Plus => 2
|
||||
Kind::Plus => 2,
|
||||
Kind::Akp153 => 3,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +132,8 @@ impl Kind {
|
||||
Kind::Mini | Kind::MiniMk2 => 3,
|
||||
Kind::Xl | Kind::XlV2 => 8,
|
||||
Kind::Pedal => 3,
|
||||
Kind::Plus => 4
|
||||
Kind::Plus => 4,
|
||||
Kind::Akp153 => 6,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +149,7 @@ impl Kind {
|
||||
pub fn lcd_strip_size(&self) -> Option<(usize, usize)> {
|
||||
match self {
|
||||
Kind::Plus => Some((800, 100)),
|
||||
Kind::Akp153 => Some((854, 480)), // logo
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -149,38 +174,45 @@ impl Kind {
|
||||
mode: ImageMode::BMP,
|
||||
size: (72, 72),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::Both
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
|
||||
Kind::OriginalV2 | Kind::Mk2 => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (72, 72),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::Both
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
|
||||
Kind::Mini | Kind::MiniMk2 => ImageFormat {
|
||||
mode: ImageMode::BMP,
|
||||
size: (80, 80),
|
||||
rotation: ImageRotation::Rot90,
|
||||
mirror: ImageMirroring::Y
|
||||
mirror: ImageMirroring::Y,
|
||||
},
|
||||
|
||||
Kind::Xl | Kind::XlV2 => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (96, 96),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::Both
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
|
||||
Kind::Plus => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (120, 120),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::None
|
||||
mirror: ImageMirroring::None,
|
||||
},
|
||||
|
||||
Kind::Pedal => ImageFormat::default(),
|
||||
|
||||
Kind::Akp153 => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (85, 85),
|
||||
rotation: ImageRotation::Rot90,
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,13 +221,8 @@ impl Kind {
|
||||
match self {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
let mut data = vec![
|
||||
0x42, 0x4d, 0xf6, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc0, 0x3c, 0x00, 0x00, 0xc4, 0x0e,
|
||||
0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x42, 0x4d, 0xf6, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xc0, 0x3c, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let (ws, hs) = self.key_image_format().size;
|
||||
@@ -206,159 +233,101 @@ impl Kind {
|
||||
}
|
||||
|
||||
Kind::OriginalV2 | Kind::Mk2 => vec![
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07, 0x07, 0x09, 0x09, 0x08,
|
||||
0x0a, 0x0c, 0x14, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a,
|
||||
0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34,
|
||||
0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x09,
|
||||
0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0d, 0x0d, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x48, 0x00, 0x48, 0x03, 0x01, 0x22, 0x00,
|
||||
0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
|
||||
0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
|
||||
0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
|
||||
0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
|
||||
0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||
0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00,
|
||||
0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04,
|
||||
0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31,
|
||||
0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
|
||||
0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
|
||||
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
|
||||
0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
|
||||
0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf9, 0xfe, 0x8a, 0x28,
|
||||
0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02,
|
||||
0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28,
|
||||
0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x0f, 0xff, 0xd9
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x08, 0x06, 0x06, 0x07, 0x06,
|
||||
0x05, 0x08, 0x07, 0x07, 0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20,
|
||||
0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff,
|
||||
0xdb, 0x00, 0x43, 0x01, 0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0d, 0x0d, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x48, 0x00, 0x48, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
|
||||
0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
|
||||
0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
|
||||
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
|
||||
0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
|
||||
0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15,
|
||||
0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
|
||||
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf9, 0xfe, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x0f, 0xff, 0xd9,
|
||||
],
|
||||
|
||||
Kind::Xl | Kind::XlV2 => vec![
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07, 0x07, 0x09, 0x09, 0x08,
|
||||
0x0a, 0x0c, 0x14, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a,
|
||||
0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34,
|
||||
0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x09,
|
||||
0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0d, 0x0d, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x60, 0x03, 0x01, 0x22, 0x00,
|
||||
0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
|
||||
0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
|
||||
0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
|
||||
0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
|
||||
0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||
0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00,
|
||||
0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04,
|
||||
0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31,
|
||||
0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
|
||||
0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
|
||||
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
|
||||
0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
|
||||
0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf9, 0xfe, 0x8a, 0x28,
|
||||
0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02,
|
||||
0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28,
|
||||
0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02,
|
||||
0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x0f, 0xff, 0xd9
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x08, 0x06, 0x06, 0x07, 0x06,
|
||||
0x05, 0x08, 0x07, 0x07, 0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20,
|
||||
0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff,
|
||||
0xdb, 0x00, 0x43, 0x01, 0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0d, 0x0d, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x60, 0x00, 0x60, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
|
||||
0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
|
||||
0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
|
||||
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
|
||||
0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
|
||||
0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15,
|
||||
0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
|
||||
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf9, 0xfe, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0,
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a,
|
||||
0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x0f, 0xff, 0xd9,
|
||||
],
|
||||
|
||||
Kind::Plus => vec![
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01,
|
||||
0x00, 0x01, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x78, 0x00, 0x78, 0x03, 0x01, 0x11,
|
||||
0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03,
|
||||
0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04,
|
||||
0x05, 0x0a, 0x07, 0x07, 0x06, 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, 0x0e,
|
||||
0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15,
|
||||
0x15, 0x0c, 0x0f, 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xff, 0xdb, 0x00, 0x43,
|
||||
0x01, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0d, 0x0b, 0x0d, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05,
|
||||
0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
|
||||
0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
|
||||
0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
|
||||
0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
|
||||
0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
|
||||
0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5,
|
||||
0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00,
|
||||
0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00,
|
||||
0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13,
|
||||
0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15,
|
||||
0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
|
||||
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
||||
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
|
||||
0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
|
||||
0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4,
|
||||
0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2,
|
||||
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
|
||||
0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xfc,
|
||||
0xaa, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80,
|
||||
0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00,
|
||||
0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02,
|
||||
0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a,
|
||||
0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28,
|
||||
0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80,
|
||||
0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00,
|
||||
0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02,
|
||||
0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a,
|
||||
0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28,
|
||||
0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80,
|
||||
0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00,
|
||||
0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02,
|
||||
0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a,
|
||||
0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28,
|
||||
0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80,
|
||||
0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x0f, 0xff, 0xd9,
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x78, 0x00, 0x78, 0x03,
|
||||
0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08,
|
||||
0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, 0x16,
|
||||
0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x09,
|
||||
0x05, 0x05, 0x09, 0x14, 0x0d, 0x0b, 0x0d, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xff, 0xc4, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
|
||||
0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
|
||||
0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
|
||||
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
|
||||
0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
|
||||
0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15,
|
||||
0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
|
||||
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xfc, 0xaa, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00,
|
||||
0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02,
|
||||
0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a,
|
||||
0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28,
|
||||
0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80,
|
||||
0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00,
|
||||
0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00,
|
||||
0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02,
|
||||
0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a,
|
||||
0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28,
|
||||
0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0,
|
||||
0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x00, 0x28, 0x00, 0xa0, 0x0f, 0xff,
|
||||
0xd9,
|
||||
],
|
||||
|
||||
_ => vec![]
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,7 +351,7 @@ impl Default for ImageFormat {
|
||||
mode: ImageMode::None,
|
||||
size: (0, 0),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::None
|
||||
mirror: ImageMirroring::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,7 +379,7 @@ pub enum ImageMirroring {
|
||||
/// Flip by Y
|
||||
Y,
|
||||
/// Flip by both axes
|
||||
Both
|
||||
Both,
|
||||
}
|
||||
|
||||
/// Image format
|
||||
@@ -421,5 +390,5 @@ pub enum ImageMode {
|
||||
/// Bitmap image
|
||||
BMP,
|
||||
/// Jpeg image
|
||||
JPEG
|
||||
}
|
||||
JPEG,
|
||||
}
|
||||
+362
-78
@@ -7,6 +7,7 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::iter::zip;
|
||||
@@ -18,8 +19,10 @@ use hidapi::{HidApi, HidDevice, HidError, HidResult};
|
||||
use image::{DynamicImage, ImageError};
|
||||
use crate::images::{convert_image, ImageRect};
|
||||
|
||||
use crate::info::{ELGATO_VENDOR_ID, Kind};
|
||||
use crate::util::{extract_str, flip_key_index, get_feature_report, read_button_states, read_data, read_encoder_input, read_lcd_input, send_feature_report, write_data};
|
||||
use crate::info::{ELGATO_VENDOR_ID, AJAZZ_VENDOR_ID, Kind};
|
||||
use crate::util::{
|
||||
extract_str, ajazz_to_elgato_input, elgato_to_ajazz, flip_key_index, get_feature_report, read_button_states, read_data, read_encoder_input, read_lcd_input, send_feature_report, write_data,
|
||||
};
|
||||
|
||||
/// Various information about Stream Deck devices
|
||||
pub mod info;
|
||||
@@ -52,9 +55,10 @@ pub fn refresh_device_list(hidapi: &mut HidApi) -> HidResult<()> {
|
||||
///
|
||||
/// **WARNING:** To refresh the list, use [refresh_device_list]
|
||||
pub fn list_devices(hidapi: &HidApi) -> Vec<(Kind, String)> {
|
||||
hidapi.device_list()
|
||||
hidapi
|
||||
.device_list()
|
||||
.filter_map(|d| {
|
||||
if d.vendor_id() != ELGATO_VENDOR_ID {
|
||||
if d.vendor_id() != AJAZZ_VENDOR_ID && d.vendor_id() != ELGATO_VENDOR_ID {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -63,14 +67,13 @@ pub fn list_devices(hidapi: &HidApi) -> Vec<(Kind, String)> {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((
|
||||
Kind::from_pid(d.product_id())?,
|
||||
serial.to_string()
|
||||
))
|
||||
Some((Kind::from_pid(d.product_id())?, serial.to_string()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -116,18 +119,17 @@ pub struct StreamDeck {
|
||||
kind: Kind,
|
||||
/// Connected HIDDevice
|
||||
device: HidDevice,
|
||||
/// Image buffers updated
|
||||
updated: bool,
|
||||
}
|
||||
|
||||
/// Static functions of the struct
|
||||
impl StreamDeck {
|
||||
/// Attempts to connect to the device
|
||||
pub fn connect(hidapi: &HidApi, kind: Kind, serial: &str) -> Result<StreamDeck, StreamDeckError> {
|
||||
let device = hidapi.open_serial(ELGATO_VENDOR_ID, kind.product_id(), serial)?;
|
||||
let device = hidapi.open_serial(kind.vendor_id(), kind.product_id(), serial)?;
|
||||
|
||||
Ok(StreamDeck {
|
||||
kind,
|
||||
device
|
||||
})
|
||||
Ok(StreamDeck { kind, device, updated: false })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +153,20 @@ impl StreamDeck {
|
||||
/// Returns serial number of the device
|
||||
pub fn serial_number(&self) -> Result<String, StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let serial = self.device.get_serial_number_string()?;
|
||||
match serial {
|
||||
Some(serial) => {
|
||||
if serial.is_empty() {
|
||||
Ok("Unknown".to_string())
|
||||
} else {
|
||||
Ok(serial)
|
||||
}
|
||||
}
|
||||
None => Ok("Unknown".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
Kind::Original | Kind::Mini => {
|
||||
let bytes = get_feature_report(&self.device, 0x03, 17)?;
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
@@ -176,6 +192,11 @@ impl StreamDeck {
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
}
|
||||
|
||||
Kind::Akp153 => {
|
||||
let bytes = get_feature_report(&self.device, 0x01, 20)?;
|
||||
Ok(extract_str(&bytes[0..])?)
|
||||
}
|
||||
|
||||
_ => {
|
||||
let bytes = get_feature_report(&self.device, 0x05, 32)?;
|
||||
Ok(extract_str(&bytes[6..])?)
|
||||
@@ -183,64 +204,75 @@ impl StreamDeck {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the image buffer has been modified.
|
||||
pub fn is_updated(&self) -> bool {
|
||||
self.updated
|
||||
}
|
||||
|
||||
/// Reads all possible input from Stream Deck device
|
||||
pub fn read_input(&self, timeout: Option<Duration>) -> Result<StreamDeckInput, StreamDeckError> {
|
||||
match &self.kind {
|
||||
Kind::Plus => {
|
||||
let data = read_data(
|
||||
&self.device,
|
||||
14.max(5 + self.kind.encoder_count() as usize),
|
||||
timeout
|
||||
)?;
|
||||
let data = read_data(&self.device, 14.max(5 + self.kind.encoder_count() as usize), timeout)?;
|
||||
|
||||
if data[0] == 0 {
|
||||
return Ok(StreamDeckInput::NoData);
|
||||
}
|
||||
|
||||
match &data[1] {
|
||||
0x0 => Ok(StreamDeckInput::ButtonStateChange(
|
||||
read_button_states(&self.kind, &data)
|
||||
)),
|
||||
0x0 => Ok(StreamDeckInput::ButtonStateChange(read_button_states(&self.kind, &data))),
|
||||
|
||||
0x2 => Ok(
|
||||
read_lcd_input(&data)?
|
||||
),
|
||||
0x2 => Ok(read_lcd_input(&data)?),
|
||||
|
||||
0x3 => Ok(
|
||||
read_encoder_input(&self.kind, &data)?
|
||||
),
|
||||
0x3 => Ok(read_encoder_input(&self.kind, &data)?),
|
||||
|
||||
_ => Err(StreamDeckError::BadData)
|
||||
_ => Err(StreamDeckError::BadData),
|
||||
}
|
||||
}
|
||||
|
||||
Kind::Akp153 => {
|
||||
let data = match self.kind {
|
||||
_ => read_data(&self.device, 512, timeout),
|
||||
}?;
|
||||
|
||||
if data[0] != 0 {
|
||||
return Ok(StreamDeckInput::NoData);
|
||||
}
|
||||
|
||||
// ack ok
|
||||
if data[0] == 65 && data[1] == 67 && data[2] == 75 && data[3] == 0 && data[4] == 0 && data[5] == 79 && data[6] == 75 && data[7] == 0 {
|
||||
return Ok(StreamDeckInput::NoData);
|
||||
}
|
||||
|
||||
let mut states = vec![0x01];
|
||||
states.extend(vec![0u8; (self.kind.key_count() + 1) as usize]);
|
||||
|
||||
if data[9] != 0 {
|
||||
let key = ajazz_to_elgato_input(&self.kind, data[9] - 1);
|
||||
|
||||
states[(key + 1) as usize] = 0x1u8;
|
||||
}
|
||||
|
||||
Ok(StreamDeckInput::ButtonStateChange(read_button_states(&self.kind, &states)))
|
||||
}
|
||||
|
||||
_ => {
|
||||
let data = match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => read_data(
|
||||
&self.device,
|
||||
1 + self.kind.key_count() as usize,
|
||||
timeout
|
||||
),
|
||||
_ => read_data(
|
||||
&self.device,
|
||||
4 + self.kind.key_count() as usize,
|
||||
timeout
|
||||
)
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => read_data(&self.device, 1 + self.kind.key_count() as usize, timeout),
|
||||
_ => read_data(&self.device, 4 + self.kind.key_count() as usize, timeout),
|
||||
}?;
|
||||
|
||||
if data[0] == 0 {
|
||||
return Ok(StreamDeckInput::NoData);
|
||||
}
|
||||
|
||||
Ok(StreamDeckInput::ButtonStateChange(
|
||||
read_button_states(&self.kind, &data)
|
||||
))
|
||||
Ok(StreamDeckInput::ButtonStateChange(read_button_states(&self.kind, &data)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resets the device
|
||||
pub fn reset(&self) -> Result<(), StreamDeckError> {
|
||||
pub fn reset(&mut self) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
let mut buf = vec![0x0B, 0x63];
|
||||
@@ -250,6 +282,11 @@ impl StreamDeck {
|
||||
Ok(send_feature_report(&self.device, buf.as_slice())?)
|
||||
}
|
||||
|
||||
Kind::Akp153 => Ok({
|
||||
self.set_brightness(100)?;
|
||||
self.clear_button_image(0xff)?;
|
||||
}),
|
||||
|
||||
_ => {
|
||||
let mut buf = vec![0x03, 0x02];
|
||||
|
||||
@@ -266,26 +303,25 @@ impl StreamDeck {
|
||||
|
||||
match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
let mut buf = vec![
|
||||
0x05,
|
||||
0x55,
|
||||
0xaa,
|
||||
0xd1,
|
||||
0x01,
|
||||
percent
|
||||
];
|
||||
let mut buf = vec![0x05, 0x55, 0xaa, 0xd1, 0x01, percent];
|
||||
|
||||
buf.extend(vec![0u8; 11]);
|
||||
|
||||
Ok(send_feature_report(&self.device, buf.as_slice())?)
|
||||
}
|
||||
|
||||
Kind::Akp153 => {
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x00, 0x00, percent];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
_ => {
|
||||
let mut buf = vec![
|
||||
0x03,
|
||||
0x08,
|
||||
percent
|
||||
];
|
||||
let mut buf = vec![0x03, 0x08, percent];
|
||||
|
||||
buf.extend(vec![0u8; 29]);
|
||||
|
||||
@@ -295,13 +331,15 @@ impl StreamDeck {
|
||||
}
|
||||
|
||||
/// Writes image data to Stream Deck device
|
||||
pub fn write_image(&self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
|
||||
pub fn write_image(&mut self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
|
||||
if key >= self.kind.key_count() {
|
||||
return Err(StreamDeckError::InvalidKeyIndex);
|
||||
}
|
||||
|
||||
let key = if let Kind::Original = self.kind {
|
||||
flip_key_index(&self.kind, key)
|
||||
} else if let Kind::Akp153 = self.kind {
|
||||
elgato_to_ajazz(&self.kind, key)
|
||||
} else {
|
||||
key
|
||||
};
|
||||
@@ -310,19 +348,47 @@ impl StreamDeck {
|
||||
return Err(StreamDeckError::NoScreen);
|
||||
}
|
||||
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let mut buf = vec![
|
||||
0x43,
|
||||
0x52,
|
||||
0x54,
|
||||
0x00,
|
||||
0x00,
|
||||
0x42,
|
||||
0x41,
|
||||
0x54,
|
||||
0x00,
|
||||
0x00,
|
||||
(image_data.len() >> 8) as u8,
|
||||
image_data.len() as u8,
|
||||
key + 1,
|
||||
];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let image_report_length = match self.kind {
|
||||
Kind::Original => 8191,
|
||||
_ => 1024
|
||||
Kind::Akp153 => 512,
|
||||
_ => 1024,
|
||||
};
|
||||
|
||||
let image_report_header_length = match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => 16,
|
||||
_ => 8
|
||||
Kind::Akp153 => 0,
|
||||
_ => 8,
|
||||
};
|
||||
|
||||
let image_report_payload_length = match self.kind {
|
||||
Kind::Original => image_data.len() / 2,
|
||||
_ => image_report_length - image_report_header_length
|
||||
_ => image_report_length - image_report_header_length,
|
||||
};
|
||||
|
||||
let mut page_number = 0;
|
||||
@@ -372,6 +438,8 @@ impl StreamDeck {
|
||||
0,
|
||||
],
|
||||
|
||||
Kind::Akp153 => vec![],
|
||||
|
||||
_ => vec![
|
||||
0x02,
|
||||
0x07,
|
||||
@@ -381,10 +449,10 @@ impl StreamDeck {
|
||||
(this_length >> 8) as u8,
|
||||
(page_number & 0xff) as u8,
|
||||
(page_number >> 8) as u8,
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
buf.extend(&image_data[bytes_sent .. bytes_sent + this_length]);
|
||||
buf.extend(&image_data[bytes_sent..bytes_sent + this_length]);
|
||||
|
||||
// Adding padding
|
||||
buf.extend(vec![0u8; image_report_length - buf.len()]);
|
||||
@@ -395,6 +463,10 @@ impl StreamDeck {
|
||||
page_number += 1;
|
||||
}
|
||||
|
||||
self.updated = true;
|
||||
// // flush
|
||||
// self.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -402,9 +474,10 @@ impl StreamDeck {
|
||||
pub fn write_lcd(&self, x: u16, y: u16, rect: &ImageRect) -> Result<(), StreamDeckError> {
|
||||
if !match self.kind {
|
||||
Kind::Plus => true,
|
||||
_ => false
|
||||
Kind::Akp153 => false,
|
||||
_ => false,
|
||||
} {
|
||||
return Err(StreamDeckError::UnsupportedOperation)
|
||||
return Err(StreamDeckError::UnsupportedOperation);
|
||||
}
|
||||
|
||||
let image_report_length = 1024;
|
||||
@@ -437,10 +510,10 @@ impl StreamDeck {
|
||||
(page_number >> 8) as u8,
|
||||
(this_length & 0xff) as u8,
|
||||
(this_length >> 8) as u8,
|
||||
0
|
||||
0,
|
||||
];
|
||||
|
||||
buf.extend(&rect.data[bytes_sent .. bytes_sent + this_length]);
|
||||
buf.extend(&rect.data[bytes_sent..bytes_sent + this_length]);
|
||||
|
||||
// Adding padding
|
||||
buf.extend(vec![0u8; image_report_length - buf.len()]);
|
||||
@@ -455,16 +528,218 @@ impl StreamDeck {
|
||||
}
|
||||
|
||||
/// Sets button's image to blank
|
||||
pub fn clear_button_image(&self, key: u8) -> Result<(), StreamDeckError> {
|
||||
Ok(self.write_image(key, &self.kind.blank_image())?)
|
||||
pub fn clear_button_image(&mut self, key: u8) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let key = elgato_to_ajazz(&self.kind, key);
|
||||
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x43, 0x4c, 0x45, 0x00, 0x00, 0x00, if key == 0xff { 0xff } else { key + 1 }];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
_ => Ok(self.write_image(key, &self.kind.blank_image())?),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets specified button's image
|
||||
pub fn set_button_image(&self, key: u8, image: DynamicImage) -> Result<(), StreamDeckError> {
|
||||
pub fn set_button_image(&mut self, key: u8, image: DynamicImage) -> Result<(), StreamDeckError> {
|
||||
let image_data = convert_image(self.kind, image)?;
|
||||
Ok(self.write_image(key, &image_data)?)
|
||||
}
|
||||
|
||||
/// Set logo image
|
||||
pub fn set_logo_image(&mut self, image: DynamicImage) -> Result<(), StreamDeckError> {
|
||||
if !match self.kind {
|
||||
Kind::Akp153 => true,
|
||||
_ => false,
|
||||
} {
|
||||
return Err(StreamDeckError::UnsupportedOperation);
|
||||
}
|
||||
|
||||
if self.kind.lcd_strip_size().is_none() {
|
||||
return Err(StreamDeckError::UnsupportedOperation);
|
||||
}
|
||||
// 854 * 480 * 3
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x4c, 0x4f, 0x47, 0x00, 0x12, 0xc3, 0xc0, 0x01];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
let mut image_buffer: DynamicImage = DynamicImage::new_rgb8(854, 480);
|
||||
|
||||
let ratio = 854.0 / 480.0;
|
||||
|
||||
let mode = "cover";
|
||||
|
||||
match mode {
|
||||
"contain" => {
|
||||
let (image_w, image_h) = (image.width(), image.height());
|
||||
let image_ratio = image_w as f32 / image_h as f32;
|
||||
|
||||
let (ws, hs) = if image_ratio > ratio {
|
||||
(854, (854.0 / image_ratio) as u32)
|
||||
} else {
|
||||
((480.0 * image_ratio) as u32, 480)
|
||||
};
|
||||
|
||||
let resized_image = image.resize(ws, hs, image::imageops::FilterType::Nearest);
|
||||
image::imageops::overlay(
|
||||
&mut image_buffer,
|
||||
&resized_image,
|
||||
((854 - resized_image.width()) / 2) as i64,
|
||||
((480 - resized_image.height()) / 2) as i64,
|
||||
);
|
||||
}
|
||||
"cover" => {
|
||||
let resized_image = image.resize_to_fill(854, 480, image::imageops::FilterType::Nearest);
|
||||
image::imageops::overlay(
|
||||
&mut image_buffer,
|
||||
&resized_image,
|
||||
((854 - resized_image.width()) / 2) as i64,
|
||||
((480 - resized_image.height()) / 2) as i64,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let (image_w, image_h) = (image.width(), image.height());
|
||||
let image_ratio = image_w as f32 / image_h as f32;
|
||||
|
||||
let (ws, hs) = if image_ratio > ratio {
|
||||
((480.0 * image_ratio) as u32, 480)
|
||||
} else {
|
||||
(854, (854.0 / image_ratio) as u32)
|
||||
};
|
||||
|
||||
let resized_image = image.resize(ws, hs, image::imageops::FilterType::Nearest);
|
||||
image::imageops::overlay(
|
||||
&mut image_buffer,
|
||||
&resized_image,
|
||||
((854 - resized_image.width()) / 2) as i64,
|
||||
((480 - resized_image.height()) / 2) as i64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut image_data = image_buffer.rotate90().fliph().flipv().into_rgb8().to_vec();
|
||||
for x in (0..image_data.len()).step_by(3) {
|
||||
(image_data[x], image_data[x + 2]) = (image_data[x + 2], image_data[x])
|
||||
}
|
||||
|
||||
let image_report_length = match self.kind {
|
||||
Kind::Original => 8191,
|
||||
Kind::Akp153 => 512,
|
||||
_ => 1024,
|
||||
};
|
||||
|
||||
let image_report_header_length = match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => 16,
|
||||
Kind::Akp153 => 0,
|
||||
_ => 8,
|
||||
};
|
||||
|
||||
let image_report_payload_length = match self.kind {
|
||||
Kind::Original => image_data.len() / 2,
|
||||
_ => image_report_length - image_report_header_length,
|
||||
};
|
||||
|
||||
let mut page_number = 0;
|
||||
let mut bytes_remaining = image_data.len();
|
||||
|
||||
while bytes_remaining > 0 {
|
||||
let this_length = bytes_remaining.min(image_report_payload_length);
|
||||
let bytes_sent = page_number * image_report_payload_length;
|
||||
|
||||
// Selecting header based on device
|
||||
let mut buf: Vec<u8> = vec![];
|
||||
|
||||
buf.extend(&image_data[bytes_sent..bytes_sent + this_length]);
|
||||
|
||||
// Adding padding
|
||||
buf.extend(vec![0u8; image_report_length - buf.len()]);
|
||||
|
||||
write_data(&self.device, &buf)?;
|
||||
|
||||
bytes_remaining -= this_length;
|
||||
page_number += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Flushes the button's image to the device
|
||||
pub fn flush(&mut self) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x53, 0x54, 0x50];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
self.updated = false;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
_ => {
|
||||
self.updated = false;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sleeps the device
|
||||
pub fn sleep(&self) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x48, 0x41, 0x4e];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Shutdown the device
|
||||
pub fn shutdown(&self) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Akp153 => {
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x53, 0x54, 0x50];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x43, 0x4c, 0x45, 0x00, 0x00, 0x00, 0xff];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x43, 0x4c, 0x45, 0x00, 0x00, 0x44, 0x43];
|
||||
|
||||
buf.extend(vec![0u8; 512 - buf.len()]);
|
||||
|
||||
write_data(&self.device, buf.as_slice())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns button state reader for this device
|
||||
pub fn get_reader(self: &Arc<Self>) -> Arc<DeviceStateReader> {
|
||||
Arc::new(DeviceStateReader {
|
||||
@@ -472,7 +747,7 @@ impl StreamDeck {
|
||||
states: Mutex::new(DeviceState {
|
||||
buttons: vec![false; self.kind.key_count() as usize],
|
||||
encoders: vec![false; self.kind.encoder_count() as usize],
|
||||
})
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -583,13 +858,13 @@ pub enum DeviceStateUpdate {
|
||||
#[derive(Default)]
|
||||
struct DeviceState {
|
||||
pub buttons: Vec<bool>,
|
||||
pub encoders: Vec<bool>
|
||||
pub encoders: Vec<bool>,
|
||||
}
|
||||
|
||||
/// Button reader that keeps state of the Stream Deck and returns events instead of full states
|
||||
pub struct DeviceStateReader {
|
||||
device: Arc<StreamDeck>,
|
||||
states: Mutex<DeviceState>
|
||||
states: Mutex<DeviceState>,
|
||||
}
|
||||
|
||||
impl DeviceStateReader {
|
||||
@@ -603,11 +878,21 @@ impl DeviceStateReader {
|
||||
match input {
|
||||
StreamDeckInput::ButtonStateChange(buttons) => {
|
||||
for (index, (their, mine)) in zip(buttons.iter(), my_states.buttons.iter()).enumerate() {
|
||||
if *their != *mine {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
} else {
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
match self.device.kind {
|
||||
Kind::Akp153 => {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if *their != *mine {
|
||||
if *their {
|
||||
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
|
||||
} else {
|
||||
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -652,9 +937,8 @@ impl DeviceStateReader {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
drop(my_states);
|
||||
|
||||
Ok(updates)
|
||||
}
|
||||
}
|
||||
}
|
||||
+76
-27
@@ -29,7 +29,7 @@ pub fn read_data(device: &HidDevice, length: usize, timeout: Option<Duration>) -
|
||||
|
||||
match timeout {
|
||||
Some(timeout) => device.read_timeout(buf.as_mut_slice(), timeout.as_millis() as i32),
|
||||
None => device.read(buf.as_mut_slice())
|
||||
None => device.read(buf.as_mut_slice()),
|
||||
}?;
|
||||
|
||||
Ok(buf)
|
||||
@@ -37,7 +37,26 @@ pub fn read_data(device: &HidDevice, length: usize, timeout: Option<Duration>) -
|
||||
|
||||
/// Writes data to [HidDevice]
|
||||
pub fn write_data(device: &HidDevice, payload: &[u8]) -> Result<usize, HidError> {
|
||||
Ok(device.write(payload)?)
|
||||
#[cfg(target_os = "windows")]
|
||||
let platform = "windows";
|
||||
#[cfg(target_os = "macos")]
|
||||
let platform = "mac";
|
||||
#[cfg(target_os = "linux")]
|
||||
let platform = "linux";
|
||||
|
||||
match platform {
|
||||
"windows" => Ok(device.write(payload)?),
|
||||
_ => {
|
||||
if payload[0] == 0 {
|
||||
let mut buf = vec![0u8; payload.len() + 1];
|
||||
buf[0] = 0;
|
||||
buf[1..].copy_from_slice(payload);
|
||||
return Ok(device.write(buf.as_slice())?);
|
||||
} else {
|
||||
Ok(device.write(payload)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts string from byte array, removing \0 symbols
|
||||
@@ -45,6 +64,43 @@ pub fn extract_str(bytes: &[u8]) -> Result<String, Utf8Error> {
|
||||
Ok(from_utf8(bytes)?.replace('\0', "").to_string())
|
||||
}
|
||||
|
||||
/*
|
||||
Ajazz's key index
|
||||
-----------------------------
|
||||
| 0d | 0a | 07 | 04 | 01 | 10 |
|
||||
|----|----|----|----|----|----|
|
||||
| 0e | 0b | 08 | 05 | 02 | 11 |
|
||||
|----|----|----|----|----|----|
|
||||
| 0f | 0c | 09 | 06 | 03 | 12 |
|
||||
-----------------------------
|
||||
Elgato's key index
|
||||
-----------------------------
|
||||
| 01 | 02 | 03 | 04 | 05 | 06 |
|
||||
|----|----|----|----|----|----|
|
||||
| 07 | 08 | 09 | 10 | 11 | 12 |
|
||||
|----|----|----|----|----|----|
|
||||
| 13 | 14 | 15 | 16 | 17 | 18 |
|
||||
-----------------------------
|
||||
*/
|
||||
|
||||
/// Converts Elgato key index to Ajazz key index
|
||||
pub fn elgato_to_ajazz(kind: &Kind, key: u8) -> u8 {
|
||||
if key < kind.key_count() {
|
||||
return [12, 9, 6, 3, 0, 15, 13, 10, 7, 4, 1, 16, 14, 11, 8, 5, 2, 17][key as usize];
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Ajazz key index to Elgato key index
|
||||
pub fn ajazz_to_elgato_input(kind: &Kind, key: u8) -> u8 {
|
||||
if key < kind.key_count() {
|
||||
return [4, 10, 16, 3, 9, 15, 2, 8, 14, 1, 7, 13, 0, 6, 12, 5, 11, 17][key as usize];
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
/// Flips key index horizontally, for use with Original v1 Stream Deck
|
||||
pub fn flip_key_index(kind: &Kind, key: u8) -> u8 {
|
||||
let col = key % kind.column_count();
|
||||
@@ -54,10 +110,20 @@ pub fn flip_key_index(kind: &Kind, key: u8) -> u8 {
|
||||
/// Reads button states, empty vector if no data
|
||||
pub fn read_button_states(kind: &Kind, states: &Vec<u8>) -> Vec<bool> {
|
||||
if states[0] == 0 {
|
||||
return vec![]
|
||||
return vec![];
|
||||
}
|
||||
|
||||
match kind {
|
||||
Kind::Akp153 => {
|
||||
let mut bools = vec![];
|
||||
|
||||
for i in 0..kind.key_count() {
|
||||
bools.push(states[(i + 1) as usize] != 0);
|
||||
}
|
||||
|
||||
bools
|
||||
}
|
||||
|
||||
Kind::Original => {
|
||||
let mut bools = vec![];
|
||||
|
||||
@@ -70,17 +136,9 @@ pub fn read_button_states(kind: &Kind, states: &Vec<u8>) -> Vec<bool> {
|
||||
bools
|
||||
}
|
||||
|
||||
Kind::Mini | Kind::MiniMk2 => {
|
||||
states[1..].iter()
|
||||
.map(|s| *s != 0)
|
||||
.collect()
|
||||
}
|
||||
Kind::Mini | Kind::MiniMk2 => states[1..].iter().map(|s| *s != 0).collect(),
|
||||
|
||||
_ => {
|
||||
states[4..].iter()
|
||||
.map(|s| *s != 0)
|
||||
.collect()
|
||||
}
|
||||
_ => states[4..].iter().map(|s| *s != 0).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,31 +155,22 @@ pub fn read_lcd_input(data: &Vec<u8>) -> Result<StreamDeckInput, StreamDeckError
|
||||
let end_x = u16::from_le_bytes([data[10], data[11]]);
|
||||
let end_y = u16::from_le_bytes([data[12], data[13]]);
|
||||
|
||||
Ok(StreamDeckInput::TouchScreenSwipe(
|
||||
(start_x, start_y),
|
||||
(end_x, end_y)
|
||||
))
|
||||
Ok(StreamDeckInput::TouchScreenSwipe((start_x, start_y), (end_x, end_y)))
|
||||
}
|
||||
|
||||
_ => Err(StreamDeckError::BadData)
|
||||
_ => Err(StreamDeckError::BadData),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads encoder input
|
||||
pub fn read_encoder_input(kind: &Kind, data: &Vec<u8>) -> Result<StreamDeckInput, StreamDeckError> {
|
||||
match &data[4] {
|
||||
0x0 => Ok(StreamDeckInput::EncoderStateChange(
|
||||
data[5..5 + kind.encoder_count() as usize].iter()
|
||||
.map(|s| *s != 0)
|
||||
.collect()
|
||||
)),
|
||||
0x0 => Ok(StreamDeckInput::EncoderStateChange(data[5..5 + kind.encoder_count() as usize].iter().map(|s| *s != 0).collect())),
|
||||
|
||||
0x1 => Ok(StreamDeckInput::EncoderTwist(
|
||||
data[5..5 + kind.encoder_count() as usize].iter()
|
||||
.map(|s| i8::from_le_bytes([*s]))
|
||||
.collect()
|
||||
data[5..5 + kind.encoder_count() as usize].iter().map(|s| i8::from_le_bytes([*s])).collect(),
|
||||
)),
|
||||
|
||||
_ => Err(StreamDeckError::BadData),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user