mirror of
https://github.com/OpenActionAPI/rust-elgato-streamdeck.git
synced 2026-10-28 09:44:56 +00:00
feat: add support for the 6/15/32 key Stream Deck Modules (#50)
This commit is contained in:
1 parent
d22585cfca
commit
cb5c6ef037
4 files changed
+54
-22
No files matched your search
@@ -9,6 +9,9 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="008f", MODE="0660"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b9", MODE="0660", TAG+="uaccess"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00ba", MODE="0660", TAG+="uaccess"
|
||||
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE="0660", TAG+="uaccess"
|
||||
@@ -21,3 +24,6 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b9", MODE="0660", TAG+="uaccess"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00ba", MODE="0660", TAG+="uaccess"
|
||||
+36
-15
@@ -23,6 +23,12 @@ pub const PID_STREAMDECK_NEO: u16 = 0x009a;
|
||||
pub const PID_STREAMDECK_PEDAL: u16 = 0x0086;
|
||||
/// Product ID of Stream Deck Plus
|
||||
pub const PID_STREAMDECK_PLUS: u16 = 0x0084;
|
||||
/// Product ID of Stream Deck Mini Mk2 Module
|
||||
pub const PID_STREAMDECK_MINI_MK2_MODULE: u16 = 0x00b8;
|
||||
/// Product ID of Stream Deck Mk2 Module
|
||||
pub const PID_STREAMDECK_MK2_MODULE: u16 = 0x00b9;
|
||||
/// Product ID of second revision of Stream Deck XL Module
|
||||
pub const PID_STREAMDECK_XL_V2_MODULE: u16 = 0x00ba;
|
||||
|
||||
const RECOGNIZED_VENDORS: [u16; 1] = [ELGATO_VENDOR_ID];
|
||||
|
||||
@@ -56,6 +62,12 @@ pub enum Kind {
|
||||
Pedal,
|
||||
/// Stream Deck Plus
|
||||
Plus,
|
||||
/// Stream Deck Mini Mk2 Module
|
||||
MiniMk2Module,
|
||||
/// Stream Deck Mk2 Module
|
||||
Mk2Module,
|
||||
/// Stream Deck XL Module
|
||||
XlV2Module,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
@@ -74,6 +86,9 @@ impl Kind {
|
||||
PID_STREAMDECK_NEO => Some(Kind::Neo),
|
||||
PID_STREAMDECK_PEDAL => Some(Kind::Pedal),
|
||||
PID_STREAMDECK_PLUS => Some(Kind::Plus),
|
||||
PID_STREAMDECK_MINI_MK2_MODULE => Some(Kind::MiniMk2Module),
|
||||
PID_STREAMDECK_MK2_MODULE => Some(Kind::Mk2Module),
|
||||
PID_STREAMDECK_XL_V2_MODULE => Some(Kind::XlV2Module),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
@@ -94,6 +109,9 @@ impl Kind {
|
||||
Kind::Neo => PID_STREAMDECK_NEO,
|
||||
Kind::Pedal => PID_STREAMDECK_PEDAL,
|
||||
Kind::Plus => PID_STREAMDECK_PLUS,
|
||||
Kind::MiniMk2Module => PID_STREAMDECK_MINI_MK2_MODULE,
|
||||
Kind::Mk2Module => PID_STREAMDECK_MK2_MODULE,
|
||||
Kind::XlV2Module => PID_STREAMDECK_XL_V2_MODULE,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,15 +129,18 @@ impl Kind {
|
||||
Kind::Neo => ELGATO_VENDOR_ID,
|
||||
Kind::Pedal => ELGATO_VENDOR_ID,
|
||||
Kind::Plus => ELGATO_VENDOR_ID,
|
||||
Kind::MiniMk2Module => ELGATO_VENDOR_ID,
|
||||
Kind::Mk2Module => ELGATO_VENDOR_ID,
|
||||
Kind::XlV2Module => ELGATO_VENDOR_ID,
|
||||
}
|
||||
}
|
||||
|
||||
/// Amount of keys the Stream Deck kind has
|
||||
pub fn key_count(&self) -> u8 {
|
||||
match self {
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor => 15,
|
||||
Kind::Mini | Kind::MiniMk2 => 6,
|
||||
Kind::Xl | Kind::XlV2 => 32,
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 15,
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 6,
|
||||
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 32,
|
||||
Kind::Pedal => 3,
|
||||
Kind::Neo | Kind::Plus => 8,
|
||||
}
|
||||
@@ -128,9 +149,9 @@ impl Kind {
|
||||
/// Amount of button rows the Stream Deck kind has
|
||||
pub fn row_count(&self) -> u8 {
|
||||
match self {
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor => 3,
|
||||
Kind::Mini | Kind::MiniMk2 => 2,
|
||||
Kind::Xl | Kind::XlV2 => 4,
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 3,
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 2,
|
||||
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 4,
|
||||
Kind::Pedal => 1,
|
||||
Kind::Neo | Kind::Plus => 2,
|
||||
}
|
||||
@@ -139,9 +160,9 @@ impl Kind {
|
||||
/// Amount of button columns the Stream Deck kind has
|
||||
pub fn column_count(&self) -> u8 {
|
||||
match self {
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor => 5,
|
||||
Kind::Mini | Kind::MiniMk2 => 3,
|
||||
Kind::Xl | Kind::XlV2 => 8,
|
||||
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 5,
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 3,
|
||||
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 8,
|
||||
Kind::Pedal => 3,
|
||||
Kind::Neo | Kind::Plus => 4,
|
||||
}
|
||||
@@ -192,21 +213,21 @@ impl Kind {
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
|
||||
Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor => ImageFormat {
|
||||
Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (72, 72),
|
||||
rotation: ImageRotation::Rot0,
|
||||
mirror: ImageMirroring::Both,
|
||||
},
|
||||
|
||||
Kind::Mini | Kind::MiniMk2 => ImageFormat {
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => ImageFormat {
|
||||
mode: ImageMode::BMP,
|
||||
size: (80, 80),
|
||||
rotation: ImageRotation::Rot90,
|
||||
mirror: ImageMirroring::X,
|
||||
},
|
||||
|
||||
Kind::Neo | Kind::Xl | Kind::XlV2 => ImageFormat {
|
||||
Kind::Neo | Kind::Xl | Kind::XlV2 | Kind::XlV2Module => ImageFormat {
|
||||
mode: ImageMode::JPEG,
|
||||
size: (96, 96),
|
||||
rotation: ImageRotation::Rot0,
|
||||
@@ -246,7 +267,7 @@ impl Kind {
|
||||
/// Returns blank image data appropriate for the Stream Deck kind
|
||||
pub fn blank_image(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
|
||||
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,
|
||||
@@ -259,7 +280,7 @@ impl Kind {
|
||||
data
|
||||
}
|
||||
|
||||
Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor => vec![
|
||||
Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 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,
|
||||
@@ -287,7 +308,7 @@ impl Kind {
|
||||
0x02, 0x8a, 0x28, 0xa0, 0x0f, 0xff, 0xd9,
|
||||
],
|
||||
|
||||
Kind::Neo | Kind::Xl | Kind::XlV2 => vec![
|
||||
Kind::Neo | Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 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,
|
||||
|
||||
+11
-6
@@ -158,7 +158,7 @@ impl StreamDeck {
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
}
|
||||
|
||||
Kind::MiniMk2 => {
|
||||
Kind::MiniMk2 | Kind::MiniMk2Module => {
|
||||
let bytes = get_feature_report(&self.device, 0x03, 32)?;
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
}
|
||||
@@ -179,6 +179,11 @@ impl StreamDeck {
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
}
|
||||
|
||||
Kind::MiniMk2Module => {
|
||||
let bytes = get_feature_report(&self.device, 0xA1, 17)?;
|
||||
Ok(extract_str(&bytes[5..])?)
|
||||
}
|
||||
|
||||
_ => {
|
||||
let bytes = get_feature_report(&self.device, 0x05, 32)?;
|
||||
Ok(extract_str(&bytes[6..])?)
|
||||
@@ -209,7 +214,7 @@ impl StreamDeck {
|
||||
|
||||
_ => {
|
||||
let data = match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => read_data(&self.device, 1 + self.kind.key_count() as usize, timeout),
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => read_data(&self.device, 1 + self.kind.key_count() as usize, timeout),
|
||||
_ => read_data(&self.device, 4 + self.kind.key_count() as usize + self.kind.touchpoint_count() as usize, timeout),
|
||||
}?;
|
||||
|
||||
@@ -225,7 +230,7 @@ impl StreamDeck {
|
||||
/// Resets the device
|
||||
pub fn reset(&self) -> Result<(), StreamDeckError> {
|
||||
match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
|
||||
let mut buf = vec![0x0B, 0x63];
|
||||
|
||||
buf.extend(vec![0u8; 15]);
|
||||
@@ -248,7 +253,7 @@ impl StreamDeck {
|
||||
let percent = percent.clamp(0, 100);
|
||||
|
||||
match self.kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
|
||||
let mut buf = vec![0x05, 0x55, 0xaa, 0xd1, 0x01, percent];
|
||||
|
||||
buf.extend(vec![0u8; 11]);
|
||||
@@ -283,7 +288,7 @@ impl StreamDeck {
|
||||
|page_number, this_length, last_package| match self.kind {
|
||||
Kind::Original => vec![0x02, 0x01, (page_number + 1) as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
|
||||
Kind::Mini | Kind::MiniMk2 => vec![0x02, 0x01, page_number as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => vec![0x02, 0x01, page_number as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
|
||||
_ => vec![
|
||||
0x02,
|
||||
@@ -524,7 +529,7 @@ impl WriteImageParameters {
|
||||
};
|
||||
|
||||
let image_report_header_length = match kind {
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 => 16,
|
||||
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 16,
|
||||
_ => 8,
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ pub fn read_button_states(kind: &Kind, states: &[u8]) -> Vec<bool> {
|
||||
bools
|
||||
}
|
||||
|
||||
Kind::Mini | Kind::MiniMk2 => states[1..].iter().map(|s| *s != 0).collect(),
|
||||
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => states[1..].iter().map(|s| *s != 0).collect(),
|
||||
|
||||
_ => states[4..].iter().map(|s| *s != 0).collect(),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user