Merge pull request #19 from streamduck-org/dev

Update library to 0.8.0
This commit is contained in:
TheJebForge authored and GitHub committed 2024-10-20 21:53:19 +03:00
commit 1f100998cb
14 files changed
+1093 -540

No files matched your search

+4
View File
@@ -9,6 +9,7 @@ SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0086", MODE="0660",
SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0084", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="009a", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}=="5548", ATTR{idProduct}=="6674", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}=="0300", ATTR{idProduct}=="1010", 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"
@@ -21,6 +22,7 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="0660"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="5548", ATTRS{idProduct}=="6674", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0300", ATTRS{idProduct}=="1010", 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"
@@ -33,6 +35,7 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="0084", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0fd9", ATTR{idProduct}=="009a", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="5548", ATTR{idProduct}=="6674", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTR{idVendor}=="0300", ATTR{idProduct}=="1010", 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"
@@ -45,3 +48,4 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="5548", ATTRS{idProduct}=="6674", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0300", ATTRS{idProduct}=="1010", MODE="0660", GROUP="plugdev"
Generated
+122 -331
View File
@@ -4,76 +4,59 @@ version = 3
[[package]]
name = "addr2line"
version = "0.21.0"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "async-recursion"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "autocfg"
version = "1.1.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
version = "0.3.69"
version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
version = "1.14.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
[[package]]
name = "byteorder"
version = "1.5.0"
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "cc"
version = "1.0.83"
version = "1.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
dependencies = [
"libc",
"shlex",
]
[[package]]
@@ -82,130 +65,26 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "elgato-streamdeck"
version = "0.7.2"
version = "0.8.0"
dependencies = [
"async-recursion",
"hidapi",
"image",
"serial_test",
"tokio",
]
[[package]]
name = "futures"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
[[package]]
name = "futures-executor"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
[[package]]
name = "futures-sink"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
[[package]]
name = "futures-task"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
[[package]]
name = "futures-util"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "gimli"
version = "0.28.0"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "hashbrown"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
[[package]]
name = "hermit-abi"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hidapi"
version = "2.6.1"
version = "2.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e58251020fe88fe0dae5ebcc1be92b4995214af84725b375d08354d0311c23c"
checksum = "03b876ecf37e86b359573c16c8366bc3eba52b689884a0fc42ba3f67203d2a8b"
dependencies = [
"cc",
"cfg-if",
@@ -216,249 +95,97 @@ dependencies = [
[[package]]
name = "image"
version = "0.25.1"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae"
dependencies = [
"bytemuck",
"byteorder",
"byteorder-lite",
"num-traits",
"zune-core",
"zune-jpeg",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.149"
version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "memchr"
version = "2.6.4"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.7.1"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler",
"adler2",
]
[[package]]
name = "num-traits"
version = "0.2.17"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
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.1"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "pin-project-lite"
version = "0.2.13"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pkg-config"
version = "0.3.27"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
]
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "rustc-demangle"
version = "0.1.23"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "scopeguard"
version = "1.2.0"
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serial_test"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d"
dependencies = [
"dashmap",
"futures",
"lazy_static",
"log",
"parking_lot",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]]
name = "smallvec"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]]
name = "syn"
version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "tokio"
version = "1.33.0"
version = "1.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
dependencies = [
"backtrace",
"num_cpus",
"pin-project-lite",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
@@ -467,13 +194,29 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
@@ -482,42 +225,90 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[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.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zune-core"
version = "0.4.12"
@@ -526,9 +317,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-jpeg"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
dependencies = [
"zune-core",
]
+3 -8
View File
@@ -2,7 +2,7 @@
name = "elgato-streamdeck"
description = "HidApi driver for Elgato Stream Decks"
authors = ["TheJebForge"]
version = "0.7.2"
version = "0.8.0"
edition = "2021"
readme = "README.md"
homepage = "https://github.com/streamduck-org"
@@ -11,23 +11,18 @@ license = "MPL-2.0"
[dependencies]
hidapi = { version = "2.6", default-features = false }
image = { version = "0.25.1", default-features = false, features = [
image = { version = "0.25.4", default-features = false, features = [
"bmp",
"jpeg",
] }
tokio = { version = "1", optional = true }
async-recursion = { version = "1.0.2", optional = true }
[dev-dependencies]
serial_test = "2.0.0"
[features]
async = [
"tokio",
"tokio/sync",
"tokio/rt-multi-thread",
"tokio/time",
"async-recursion",
"tokio/time"
]
[package.metadata.docs.rs]
+1
View File
@@ -77,3 +77,4 @@ But as it stands, this library should support following devices:
- Stream Deck Plus (thanks to [node-elgato-stream-deck](https://github.com/Julusian/node-elgato-stream-deck))
- Stream Deck Neo (thanks to [@ejiektpobehuk](https://github.com/ejiektpobehuk), [@AkechiShiro](https://github.com/AkechiShiro) and [node-elgato-stream-deck](https://github.com/Julusian/node-elgato-stream-deck))
- Ajazz AKP153 (thanks to [@ZCube](https://github.com/ZCube))
- Ajazz AKP153E (thanks to [@teras](https://github.com/teras))
+521
View File
@@ -0,0 +1,521 @@
# 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"
version = "0.0.0"
dependencies = [
"async-recursion",
"elgato-streamdeck",
"hidapi",
"image",
"tokio",
]
[[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-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[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 = "elgato-streamdeck"
version = "0.8.0"
dependencies = [
"async-recursion",
"hidapi",
"image",
"tokio",
]
[[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.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae"
dependencies = [
"bytemuck",
"byteorder-lite",
"num-traits",
"zune-core",
"zune-jpeg",
]
[[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 = "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"
[[package]]
name = "zune-core"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-jpeg"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
dependencies = [
"zune-core",
]
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "async"
edition = "2021"
[dependencies]
hidapi = { version = "2.6", default-features = false }
image = { version = "0.25.1", default-features = false, features = [
"bmp",
"jpeg",
] }
tokio = { version = "1", optional = false, features = ["full"] }
async-recursion = { version = "1.0.2", optional = false }
elgato-streamdeck = { path = "../../", features = ["async"] }
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

+143
View File
@@ -0,0 +1,143 @@
use std::time::Duration;
use image::open;
use elgato_streamdeck::{DeviceStateUpdate, list_devices, new_hidapi, AsyncStreamDeck};
use elgato_streamdeck::images::{convert_image_with_format, ImageRect};
use tokio::time::sleep;
#[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 device = AsyncStreamDeck::connect(&hid, kind, &serial).expect("Failed to connect");
// Print out some info from the device
println!("Connected to '{}' with version '{}'", device.serial_number().await.unwrap(), device.firmware_version().await.unwrap());
device.set_brightness(50).await.unwrap();
device.clear_all_button_images().await.unwrap();
// Use image-rs to load an image
let image = open("no-place-like-localhost.jpg").unwrap();
let alternative = image.grayscale().brighten(-50);
// device.set_logo_image(image.clone()).await.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()).await.unwrap();
}
println!("Touch point count: {}", kind.touchpoint_count());
for i in 0..kind.touchpoint_count() as u8 {
device.set_touchpoint_color(i, 255, 255, 255).await.unwrap();
}
if let Some(format) = device.kind().lcd_image_format() {
let scaled_image = image.clone().resize_to_fill(format.size.0 as u32, format.size.1 as u32, image::imageops::FilterType::Nearest);
let converted_image = convert_image_with_format(format, scaled_image).unwrap();
let _ = device.write_lcd_fill(&converted_image).await;
}
let small = match device.kind().lcd_strip_size() {
Some((w, h)) => {
let min = w.min(h) as u32;
let scaled_image = image.clone().resize_to_fill(min, min, image::imageops::Nearest);
Some(ImageRect::from_image(scaled_image).unwrap())
}
None => None,
};
// Flush
device.flush().await.unwrap();
// Start new task to animate the button images
let device_clone = device.clone();
tokio::spawn(async move {
let mut index = 0;
let mut previous = 0;
loop {
device_clone.set_button_image(index, image.clone()).await.unwrap();
device_clone.set_button_image(previous, alternative.clone()).await.unwrap();
device_clone.flush().await.unwrap();
sleep(Duration::from_secs_f32(0.5)).await;
previous = index;
index += 1;
if index >= kind.key_count() as u8 {
index = 0;
}
}
});
let reader = device.get_reader();
'infinite: loop {
let updates = match reader.read(100.0).await {
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);
if key == device.kind().key_count() - 1 {
break 'infinite;
}
}
DeviceStateUpdate::EncoderTwist(dial, ticks) => {
println!("Dial {} twisted by {}", dial, ticks);
}
DeviceStateUpdate::EncoderDown(dial) => {
println!("Dial {} down", dial);
}
DeviceStateUpdate::EncoderUp(dial) => {
println!("Dial {} up", dial);
}
DeviceStateUpdate::TouchPointDown(point) => {
println!("Touch point {} down", point);
}
DeviceStateUpdate::TouchPointUp(point) => {
println!("Touch point {} up", point);
}
DeviceStateUpdate::TouchScreenPress(x, y) => {
println!("Touch Screen press at {x}, {y}");
if let Some(small) = &small {
device.write_lcd(x, y, small).await.unwrap();
}
}
DeviceStateUpdate::TouchScreenLongPress(x, y) => {
println!("Touch Screen long press at {x}, {y}")
}
DeviceStateUpdate::TouchScreenSwipe((sx, sy), (ex, ey)) => {
println!("Touch Screen swipe from {sx}, {sy} to {ex}, {ey}")
}
}
}
}
drop(reader);
device.shutdown().await.ok();
}
}
Err(e) => eprintln!("Failed to create HidApi instance: {}", e),
}
}
+9 -9
View File
@@ -62,10 +62,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
[[package]]
name = "byteorder"
version = "1.5.0"
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "bytes"
@@ -87,7 +87,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "elgato-streamdeck"
version = "0.7.0"
version = "0.8.0"
dependencies = [
"hidapi",
"image",
@@ -120,12 +120,12 @@ dependencies = [
[[package]]
name = "image"
version = "0.25.1"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae"
dependencies = [
"bytemuck",
"byteorder",
"byteorder-lite",
"num-traits",
"zune-core",
"zune-jpeg",
@@ -511,9 +511,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-jpeg"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
dependencies = [
"zune-core",
]
+2 -4
View File
@@ -15,7 +15,7 @@ fn main() {
println!("{:?} {} {}", kind, serial, kind.product_id());
// Connect to the device
let mut device = StreamDeck::connect(&hid, kind, &serial).expect("Failed to connect");
let 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());
@@ -53,9 +53,7 @@ fn main() {
};
// Flush
if device.is_updated() {
device.flush().unwrap();
}
device.flush().unwrap();
let device = Arc::new(device);
{
+104 -99
View File
@@ -57,39 +57,34 @@ impl AsyncStreamDeck {
/// Returns manufacturer string of the device
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())?)
let device = self.device.lock().await;
Ok(block_in_place(move || device.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())?)
let device = self.device.lock().await;
Ok(block_in_place(move || device.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())?)
let device = self.device.lock().await;
Ok(block_in_place(move || device.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())?)
let device = self.device.lock().await;
Ok(block_in_place(move || device.firmware_version())?)
}
/// Reads button states, awaits until there's data.
/// Poll rate determines how often button state gets checked
pub async fn read_input(&self, poll_rate: f32) -> Result<StreamDeckInput, StreamDeckError> {
loop {
let device = self.device.clone();
let lock = device.lock().await;
let data = block_in_place(move || lock.read_input(None))?;
let device = self.device.lock().await;
let data = block_in_place(move || device.read_input(None))?;
if !data.is_empty() {
return Ok(data);
@@ -99,6 +94,98 @@ impl AsyncStreamDeck {
}
}
/// Resets the device
pub async fn reset(&self) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.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.lock().await;
Ok(block_in_place(move || device.set_brightness(percent))?)
}
/// Writes image data to Stream Deck device, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub async fn write_image(&self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.write_image(key, image_data))?)
}
/// Writes image data to Stream Deck device's lcd strip/screen as region.
/// Only Stream Deck Plus supports writing LCD regions, for Stream Deck Neo use write_lcd_fill
pub async fn write_lcd(&self, x: u16, y: u16, rect: &ImageRect) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.write_lcd(x, y, rect))?)
}
/// Writes image data to Stream Deck device's lcd strip/screen as full fill
///
/// You can convert your images into proper image_data like this:
/// ```
/// use elgato_streamdeck::images::{convert_image_with_format_async};
/// let image_data = convert_image_with_format_async(device.kind().lcd_image_format(), image).await.unwrap();
/// device.write_lcd_fill(&image_data).await;
/// ```
pub async fn write_lcd_fill(&self, image_data: &[u8]) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.write_lcd_fill(image_data))?)
}
/// Sets button's image to blank, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub async fn clear_button_image(&self, key: u8) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.clear_button_image(key))?)
}
/// Sets blank images to every button, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub async fn clear_all_button_images(&self) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.clear_all_button_images())?)
}
/// Sets specified button's image, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub async fn set_button_image(&self, key: u8, image: DynamicImage) -> Result<(), StreamDeckError> {
let image = convert_image_async(self.kind, image)?;
let device = self.device.lock().await;
Ok(block_in_place(move || device.write_image(key, &image))?)
}
/// Set logo image
pub async fn set_logo_image(&self, image: DynamicImage) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.set_logo_image(image))?)
}
/// Sets specified touch point's led strip color
pub async fn set_touchpoint_color(&self, point: u8, red: u8, green: u8, blue: u8) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.set_touchpoint_color(point, red, green, blue))?)
}
/// Sleeps the device
pub async fn sleep(&self) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.sleep())?)
}
/// Shutdown the device
pub async fn shutdown(&self) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.shutdown())?)
}
/// Flushes the button's image to the device
pub async fn flush(&self) -> Result<(), StreamDeckError> {
let device = self.device.lock().await;
Ok(block_in_place(move || device.flush())?)
}
/// Returns button state reader for this device
pub fn get_reader(&self) -> Arc<AsyncDeviceStateReader> {
Arc::new(AsyncDeviceStateReader {
@@ -109,83 +196,6 @@ impl AsyncStreamDeck {
}),
})
}
/// Resets the device
pub async fn reset(&self) -> Result<(), StreamDeckError> {
let device = self.device.clone();
let lock = device.lock().await;
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))?)
}
/// Writes image data to Stream Deck device
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))?)
}
/// Writes image data to Stream Deck device's lcd strip/screen as region.
/// Only Stream Deck Plus supports writing LCD regions, for Stream Deck Neo use write_lcd_fill
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))?)
}
/// Writes image data to Stream Deck device's lcd strip/screen as full fill
///
/// You can convert your images into proper image_data like this:
/// ```
/// use elgato_streamdeck::images::{convert_image_with_format_async};
/// let image_data = convert_image_with_format_async(device.kind().lcd_image_format(), image).await.unwrap();
/// device.write_lcd_fill(&image_data).await;
/// ```
pub async fn write_lcd_fill(&self, image_data: &[u8]) -> Result<(), StreamDeckError> {
let device = self.device.clone();
let lock = device.lock().await;
Ok(block_in_place(move || lock.write_lcd_fill(image_data))?)
}
/// Sets button's image to blank
pub async fn clear_button_image(&self, key: u8) -> Result<(), StreamDeckError> {
let image = self.kind.blank_image();
let device = self.device.clone();
let lock = device.lock().await;
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 blank images to every button
pub async fn clear_all_button_images(&self) -> Result<(), StreamDeckError> {
let device = self.device.clone();
let lock = device.lock().await;
Ok(block_in_place(move || lock.clear_all_button_images())?)
}
/// Sets specified button's image
pub async fn set_button_image(&self, key: u8, image: DynamicImage) -> Result<(), StreamDeckError> {
let image = convert_image_async(self.kind, image)?;
let device = self.device.clone();
let lock = device.lock().await;
Ok(block_in_place(move || lock.write_image(key, &image))?)
}
/// Sets specified touch point's led strip color
pub async fn set_touchpoint_color(&mut self, point: u8, red: u8, green: u8, blue: u8) -> Result<(), StreamDeckError> {
let device = self.device.clone();
let lock = device.lock().await;
Ok(block_in_place(move || lock.set_touchpoint_color(point, red, green, blue))?)
}
}
/// Button reader that keeps state of the Stream Deck and returns events instead of full states
@@ -196,7 +206,6 @@ pub struct AsyncDeviceStateReader {
impl AsyncDeviceStateReader {
/// Reads states and returns updates
#[async_recursion::async_recursion]
pub async fn read(&self, poll_rate: f32) -> Result<Vec<DeviceStateUpdate>, StreamDeckError> {
let input = self.device.read_input(poll_rate).await?;
let mut my_states = self.states.lock().await;
@@ -207,7 +216,7 @@ impl AsyncDeviceStateReader {
StreamDeckInput::ButtonStateChange(buttons) => {
for (index, (their, mine)) in zip(buttons.iter(), my_states.buttons.iter()).enumerate() {
match self.device.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
if *their {
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
@@ -275,10 +284,6 @@ impl AsyncDeviceStateReader {
drop(my_states);
if updates.is_empty() {
self.read(poll_rate).await
} else {
Ok(updates)
}
Ok(updates)
}
}
+55 -23
View File
@@ -23,11 +23,29 @@ pub const PID_STREAMDECK_PEDAL: u16 = 0x0086;
pub const PID_STREAMDECK_PLUS: u16 = 0x0084;
/// Vendor ID of Ajazz Stream Deck
pub const AJAZZ_VENDOR_ID: u16 = 0x5548;
pub const AJAZZ_VENDOR_ID_1: u16 = 0x5548;
/// Product ID of Ajazz Stream Deck AK153
/// Product ID of Ajazz Stream Deck AKP153
pub const PID_AJAZZ_AKP153: u16 = 0x6674;
/// Vendor ID of Ajazz Stream Deck AKP153E
pub const AJAZZ_VENDOR_ID_2: u16 = 0x0300;
/// Product ID of Ajazz Stream Deck AKP153E
pub const PID_AJAZZ_E_AKP153E: u16 = 0x1010;
const RECOGNIZED_VENDORS: &'static [u16] = &[
ELGATO_VENDOR_ID,
AJAZZ_VENDOR_ID_1,
AJAZZ_VENDOR_ID_2
];
/// Returns true for vendors IDs that are recognized by the library
pub fn is_vendor_familiar(vendor: &u16) -> bool {
RECOGNIZED_VENDORS.contains(vendor)
}
/// Enum describing kinds of Stream Decks out there
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum Kind {
@@ -51,26 +69,37 @@ pub enum Kind {
Pedal,
/// Stream Deck Plus
Plus,
/// Ajazz Stream Deck AK153
/// Ajazz Stream Deck AKP153
Akp153,
/// Ajazz Stream Deck AKP153E
Akp153E,
}
impl Kind {
/// Creates [Kind] variant from Product ID
pub fn from_pid(pid: u16) -> Option<Kind> {
match pid {
PID_STREAMDECK_ORIGINAL => Some(Kind::Original),
PID_STREAMDECK_ORIGINAL_V2 => Some(Kind::OriginalV2),
PID_STREAMDECK_MINI => Some(Kind::Mini),
PID_STREAMDECK_XL => Some(Kind::Xl),
PID_STREAMDECK_XL_V2 => Some(Kind::XlV2),
PID_STREAMDECK_MK2 => Some(Kind::Mk2),
PID_STREAMDECK_MINI_MK2 => Some(Kind::MiniMk2),
PID_STREAMDECK_NEO => Some(Kind::Neo),
PID_STREAMDECK_PEDAL => Some(Kind::Pedal),
PID_STREAMDECK_PLUS => Some(Kind::Plus),
PID_AJAZZ_AKP153 => Some(Kind::Akp153),
_ => None,
/// Creates [Kind] variant from Vendor ID and Product ID
pub fn from_vid_pid(vid: u16, pid: u16) -> Option<Kind> {
match vid {
ELGATO_VENDOR_ID => match pid {
PID_STREAMDECK_ORIGINAL => Some(Kind::Original),
PID_STREAMDECK_ORIGINAL_V2 => Some(Kind::OriginalV2),
PID_STREAMDECK_MINI => Some(Kind::Mini),
PID_STREAMDECK_XL => Some(Kind::Xl),
PID_STREAMDECK_XL_V2 => Some(Kind::XlV2),
PID_STREAMDECK_MK2 => Some(Kind::Mk2),
PID_STREAMDECK_MINI_MK2 => Some(Kind::MiniMk2),
PID_STREAMDECK_NEO => Some(Kind::Neo),
PID_STREAMDECK_PEDAL => Some(Kind::Pedal),
PID_STREAMDECK_PLUS => Some(Kind::Plus),
_ => None
},
AJAZZ_VENDOR_ID_1 | AJAZZ_VENDOR_ID_2 => match pid {
PID_AJAZZ_AKP153 => Some(Kind::Akp153),
PID_AJAZZ_E_AKP153E => Some(Kind::Akp153E),
_ => None
}
_ => None
}
}
@@ -88,6 +117,7 @@ impl Kind {
Kind::Pedal => PID_STREAMDECK_PEDAL,
Kind::Plus => PID_STREAMDECK_PLUS,
Kind::Akp153 => PID_AJAZZ_AKP153,
Kind::Akp153E => PID_AJAZZ_E_AKP153E,
}
}
@@ -104,7 +134,8 @@ impl Kind {
Kind::Neo => ELGATO_VENDOR_ID,
Kind::Pedal => ELGATO_VENDOR_ID,
Kind::Plus => ELGATO_VENDOR_ID,
Kind::Akp153 => AJAZZ_VENDOR_ID,
Kind::Akp153 => AJAZZ_VENDOR_ID_1,
Kind::Akp153E => AJAZZ_VENDOR_ID_2,
}
}
@@ -116,7 +147,7 @@ impl Kind {
Kind::Xl | Kind::XlV2 => 32,
Kind::Pedal => 3,
Kind::Neo | Kind::Plus => 8,
Kind::Akp153 => 15 + 3,
Kind::Akp153 | Kind::Akp153E => 15 + 3,
}
}
@@ -128,7 +159,7 @@ impl Kind {
Kind::Xl | Kind::XlV2 => 4,
Kind::Pedal => 1,
Kind::Neo | Kind::Plus => 2,
Kind::Akp153 => 3,
Kind::Akp153 | Kind::Akp153E => 3,
}
}
@@ -141,6 +172,7 @@ impl Kind {
Kind::Pedal => 3,
Kind::Neo | Kind::Plus => 4,
Kind::Akp153 => 6,
Kind::Akp153E => 6,
}
}
@@ -165,7 +197,7 @@ impl Kind {
match self {
Kind::Plus => Some((800, 100)),
Kind::Neo => Some((248, 58)),
Kind::Akp153 => Some((854, 480)), // logo
Kind::Akp153 | Kind::Akp153E => Some((854, 480)), // logo
_ => None,
}
}
@@ -223,7 +255,7 @@ impl Kind {
Kind::Pedal => ImageFormat::default(),
Kind::Akp153 => ImageFormat {
Kind::Akp153 | Kind::Akp153E => ImageFormat {
mode: ImageMode::JPEG,
size: (85, 85),
rotation: ImageRotation::Rot90,
+115 -65
View File
@@ -12,17 +12,18 @@ use std::error::Error;
use std::fmt::{Display, Formatter};
use std::iter::zip;
use std::str::Utf8Error;
use std::sync::{Arc, Mutex, PoisonError};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::RwLock;
use std::sync::{Arc, Mutex, PoisonError};
use std::time::Duration;
use crate::images::{convert_image, ImageRect};
use hidapi::{HidApi, HidDevice, HidError, HidResult};
use image::{DynamicImage, ImageError};
use crate::images::{convert_image, ImageRect};
use crate::info::{ELGATO_VENDOR_ID, AJAZZ_VENDOR_ID, Kind};
use crate::info::{is_vendor_familiar, 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,
ajazz_to_elgato_input, elgato_to_ajazz, extract_str, 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
@@ -59,12 +60,12 @@ pub fn list_devices(hidapi: &HidApi) -> Vec<(Kind, String)> {
hidapi
.device_list()
.filter_map(|d| {
if d.vendor_id() != AJAZZ_VENDOR_ID && d.vendor_id() != ELGATO_VENDOR_ID {
if !is_vendor_familiar(&d.vendor_id()) {
return None;
}
if let Some(serial) = d.serial_number() {
Some((Kind::from_pid(d.product_id())?, serial.to_string()))
Some((Kind::from_vid_pid(d.vendor_id(), d.product_id())?, serial.to_string()))
} else {
None
}
@@ -116,8 +117,15 @@ pub struct StreamDeck {
kind: Kind,
/// Connected HIDDevice
device: HidDevice,
/// Image buffers updated
updated: AtomicBool,
/// Temporarily cache the image before sending it to the device
image_cache: RwLock<Vec<ImageCache>>,
/// Device needs to be initialized
initialized: AtomicBool,
}
struct ImageCache {
key: u8,
image_data: Vec<u8>,
}
/// Static functions of the struct
@@ -126,7 +134,7 @@ impl StreamDeck {
pub fn connect(hidapi: &HidApi, kind: Kind, serial: &str) -> Result<StreamDeck, StreamDeckError> {
let device = hidapi.open_serial(kind.vendor_id(), kind.product_id(), serial)?;
Ok(StreamDeck { kind, device, updated: false.into() })
Ok(StreamDeck { kind, device, image_cache: RwLock::new(vec![]), initialized: false.into() })
}
}
@@ -150,7 +158,7 @@ impl StreamDeck {
/// Returns serial number of the device
pub fn serial_number(&self) -> Result<String, StreamDeckError> {
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let serial = self.device.get_serial_number_string()?;
match serial {
Some(serial) => {
@@ -189,7 +197,7 @@ impl StreamDeck {
Ok(extract_str(&bytes[5..])?)
}
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let bytes = get_feature_report(&self.device, 0x01, 20)?;
Ok(extract_str(&bytes[0..])?)
}
@@ -201,13 +209,29 @@ impl StreamDeck {
}
}
/// Returns whether the image buffer has been modified.
pub fn is_updated(&self) -> bool {
self.updated.load(Ordering::Acquire)
/// Initializes the device
fn initialize(&self) -> Result<(), StreamDeckError> {
if self.initialized.load(Ordering::Acquire) {
return Ok(());
}
self.initialized.store(true, Ordering::Release);
match self.kind {
Kind::Akp153 | Kind::Akp153E => {
// CRT\x00\x00DIS
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x00, 0x00, 0x00, 0x00];
buf.extend(vec![0u8; 512 - buf.len()]);
write_data(&self.device, buf.as_slice())?;
}
_ => {
}
}
Ok(())
}
/// Reads all possible input from Stream Deck device
pub fn read_input(&self, timeout: Option<Duration>) -> Result<StreamDeckInput, StreamDeckError> {
self.initialize()?;
match &self.kind {
Kind::Plus => {
let data = read_data(&self.device, 14.max(5 + self.kind.encoder_count() as usize), timeout)?;
@@ -227,17 +251,12 @@ impl StreamDeck {
}
}
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
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 {
if data[0] == 0 {
return Ok(StreamDeckInput::NoData);
}
@@ -270,6 +289,7 @@ impl StreamDeck {
/// Resets the device
pub fn reset(&self) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
let mut buf = vec![0x0B, 0x63];
@@ -279,7 +299,7 @@ impl StreamDeck {
Ok(send_feature_report(&self.device, buf.as_slice())?)
}
Kind::Akp153 => Ok({
Kind::Akp153 | Kind::Akp153E => Ok({
self.set_brightness(100)?;
self.clear_button_image(0xff)?;
}),
@@ -296,6 +316,7 @@ impl StreamDeck {
/// Sets brightness of the device, value range is 0 - 100
pub fn set_brightness(&self, percent: u8) -> Result<(), StreamDeckError> {
self.initialize()?;
let percent = percent.max(0).min(100);
match self.kind {
@@ -307,7 +328,7 @@ impl StreamDeck {
Ok(send_feature_report(&self.device, buf.as_slice())?)
}
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x00, 0x00, percent];
buf.extend(vec![0u8; 512 - buf.len()]);
@@ -327,15 +348,14 @@ impl StreamDeck {
}
}
/// Writes image data to Stream Deck device
pub fn write_image(&self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
fn send_image(&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 {
} else if let Kind::Akp153 | Kind::Akp153E = self.kind {
elgato_to_ajazz(&self.kind, key)
} else {
key
@@ -346,7 +366,7 @@ impl StreamDeck {
}
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let mut buf = vec![
0x43,
0x52,
@@ -413,8 +433,8 @@ impl StreamDeck {
0,
0,
],
Kind::Akp153 => vec![],
Kind::Akp153 | Kind::Akp153E => vec![],
_ => vec![
0x02,
@@ -429,10 +449,18 @@ impl StreamDeck {
}
}
)?;
Ok(())
}
self.updated.store(true, Ordering::Release);
// // flush
// self.flush()?;
/// Writes image data to Stream Deck device, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub fn write_image(&self, key: u8, image_data: &[u8]) -> Result<(), StreamDeckError> {
let cache_entry = ImageCache {
key,
image_data: image_data.to_vec(), // Convert &[u8] to Vec<u8>
};
self.image_cache.write()?.push(cache_entry);
Ok(())
}
@@ -440,6 +468,7 @@ impl StreamDeck {
/// Writes image data to Stream Deck device's lcd strip/screen as region.
/// Only Stream Deck Plus supports writing LCD regions, for Stream Deck Neo use write_lcd_fill
pub fn write_lcd(&self, x: u16, y: u16, rect: &ImageRect) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Plus => (),
_ => {
@@ -483,6 +512,7 @@ impl StreamDeck {
/// device.write_lcd_fill(&image_data);
/// ```
pub fn write_lcd_fill(&self, image_data: &[u8]) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Neo => {
self.write_image_data_reports(
@@ -538,10 +568,12 @@ impl StreamDeck {
}
}
/// Sets button's image to blank
/// Sets button's image to blank, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub fn clear_button_image(&self, key: u8) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
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 }];
@@ -553,14 +585,16 @@ impl StreamDeck {
Ok(())
}
_ => Ok(self.write_image(key, &self.kind.blank_image())?),
_ => Ok(self.send_image(key, &self.kind.blank_image())?),
}
}
/// Sets blank images to every button
/// Sets blank images to every button, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub fn clear_all_button_images(&self) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
self.clear_button_image(0xff)
}
_ => {
@@ -572,16 +606,19 @@ impl StreamDeck {
}
}
/// Sets specified button's image
/// Sets specified button's image, changes must be flushed with `.flush()` before
/// they will appear on the device!
pub fn set_button_image(&self, key: u8, image: DynamicImage) -> Result<(), StreamDeckError> {
self.initialize()?;
let image_data = convert_image(self.kind, image)?;
Ok(self.write_image(key, &image_data)?)
}
/// Set logo image
pub fn set_logo_image(&self, image: DynamicImage) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Akp153 => (),
Kind::Akp153 | Kind::Akp153E => (),
_ => {
return Err(StreamDeckError::UnsupportedOperation)
}
@@ -658,13 +695,13 @@ impl StreamDeck {
let image_report_length = match self.kind {
Kind::Original => 8191,
Kind::Akp153 => 512,
Kind::Akp153 | Kind::Akp153E => 512,
_ => 1024,
};
let image_report_header_length = match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 => 16,
Kind::Akp153 => 0,
Kind::Akp153 | Kind::Akp153E => 0,
_ => 8,
};
@@ -697,27 +734,9 @@ impl StreamDeck {
Ok(())
}
/// Flushes the button's image to the device
pub fn flush(&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.store(false, Ordering::Release);
Ok(())
}
/// Sets specified touch point's led strip color
pub fn set_touchpoint_color(&self, point: u8, red: u8, green: u8, blue: u8) -> Result<(), StreamDeckError> {
self.initialize()?;
if point >= self.kind.touchpoint_count() {
return Err(StreamDeckError::InvalidTouchPointIndex);
}
@@ -733,8 +752,9 @@ impl StreamDeck {
/// Sleeps the device
pub fn sleep(&self) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x48, 0x41, 0x4e];
buf.extend(vec![0u8; 512 - buf.len()]);
@@ -750,8 +770,9 @@ impl StreamDeck {
/// Shutdown the device
pub fn shutdown(&self) -> Result<(), StreamDeckError> {
self.initialize()?;
match self.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x53, 0x54, 0x50];
buf.extend(vec![0u8; 512 - buf.len()]);
@@ -777,6 +798,35 @@ impl StreamDeck {
}
}
/// Flushes the button's image to the device
pub fn flush(&self) -> Result<(), StreamDeckError> {
self.initialize()?;
if self.image_cache.write()?.len() == 0 {
return Ok(());
}
for image in self.image_cache.read()?.iter() {
self.send_image(image.key, &image.image_data)?;
}
match self.kind {
Kind::Akp153 | Kind::Akp153E => {
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.image_cache.write()?.clear();
Ok(())
}
/// Returns button state reader for this device
pub fn get_reader(self: &Arc<Self>) -> Arc<DeviceStateReader> {
Arc::new(DeviceStateReader {
@@ -835,13 +885,13 @@ impl WriteImageParameters {
pub fn for_key(kind: Kind, image_data_len: usize) -> Self {
let image_report_length = match kind {
Kind::Original => 8191,
Kind::Akp153 => 512,
Kind::Akp153 | Kind::Akp153E => 512,
_ => 1024,
};
let image_report_header_length = match kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 => 16,
Kind::Akp153 => 0,
Kind::Akp153 | Kind::Akp153E => 0,
_ => 8,
};
@@ -994,7 +1044,7 @@ impl DeviceStateReader {
StreamDeckInput::ButtonStateChange(buttons) => {
for (index, (their, mine)) in zip(buttons.iter(), my_states.buttons.iter()).enumerate() {
match self.device.kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
if *their {
updates.push(DeviceStateUpdate::ButtonDown(index as u8));
updates.push(DeviceStateUpdate::ButtonUp(index as u8));
+1 -1
View File
@@ -114,7 +114,7 @@ pub fn read_button_states(kind: &Kind, states: &Vec<u8>) -> Vec<bool> {
}
match kind {
Kind::Akp153 => {
Kind::Akp153 | Kind::Akp153E => {
let mut bools = vec![];
for i in 0..kind.key_count() {