From 7d59845a4201b25a4eaa4df80b0f50766c3205a3 Mon Sep 17 00:00:00 2001 From: Panayotis Date: Fri, 22 Nov 2024 07:05:44 -1000 Subject: [PATCH] Merge pull request #20 * Support of Ajazz Akp815 device * forgot to add the device to README * Add udev rules for Akp815 --- 40-streamdeck.rules | 4 ++ README.md | 1 + src/asynchronous.rs | 8 +++- src/info.rs | 36 ++++++++++++----- src/lib.rs | 98 ++++++++++++++++++++++++++------------------- src/util.rs | 56 ++++++++++++++++++-------- 6 files changed, 136 insertions(+), 67 deletions(-) diff --git a/40-streamdeck.rules b/40-streamdeck.rules index 5e4699f..1ab9f8b 100644 --- a/40-streamdeck.rules +++ b/40-streamdeck.rules @@ -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}=="5548", ATTR{idProduct}=="6672", 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" @@ -22,6 +23,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}=="5548", ATTRS{idProduct}=="6672", 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" @@ -35,6 +37,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}=="5548", ATTR{idProduct}=="6672", 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" @@ -48,4 +51,5 @@ 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}=="5548", ATTRS{idProduct}=="6672", MODE="0660", GROUP="plugdev" KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0300", ATTRS{idProduct}=="1010", MODE="0660", GROUP="plugdev" diff --git a/README.md b/README.md index 2a81fd6..f0cff62 100644 --- a/README.md +++ b/README.md @@ -78,3 +78,4 @@ But as it stands, this library should support following devices: - 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)) +- Ajazz AKP815 (thanks to [@teras](https://github.com/teras)) diff --git a/src/asynchronous.rs b/src/asynchronous.rs index 2a2cdda..870e4b5 100644 --- a/src/asynchronous.rs +++ b/src/asynchronous.rs @@ -174,6 +174,12 @@ impl AsyncStreamDeck { Ok(block_in_place(move || device.sleep())?) } + /// Make periodic events to the device, to keep it alive + pub async fn keep_alive(&self) -> Result<(), StreamDeckError> { + let device = self.device.lock().await; + Ok(block_in_place(move || device.keep_alive())?) + } + /// Shutdown the device pub async fn shutdown(&self) -> Result<(), StreamDeckError> { let device = self.device.lock().await; @@ -216,7 +222,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::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { if *their { updates.push(DeviceStateUpdate::ButtonDown(index as u8)); updates.push(DeviceStateUpdate::ButtonUp(index as u8)); diff --git a/src/info.rs b/src/info.rs index a838b01..f185745 100644 --- a/src/info.rs +++ b/src/info.rs @@ -22,16 +22,19 @@ 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 +/// Vendor ID of Ajazz Desk Controller pub const AJAZZ_VENDOR_ID_1: u16 = 0x5548; -/// Product ID of Ajazz Stream Deck AKP153 +/// Product ID of Ajazz AKP153 Desk Controller pub const PID_AJAZZ_AKP153: u16 = 0x6674; -/// Vendor ID of Ajazz Stream Deck AKP153E +/// Product ID of Ajazz AKP815 Desk Controller +pub const PID_AJAZZ_AKP815: u16 = 0x6672; + +/// Vendor ID of Ajazz AKP153E Desk Controller pub const AJAZZ_VENDOR_ID_2: u16 = 0x0300; -/// Product ID of Ajazz Stream Deck AKP153E +/// Product ID of Ajazz AKP153E Desk Controller pub const PID_AJAZZ_E_AKP153E: u16 = 0x1010; const RECOGNIZED_VENDORS: &'static [u16] = &[ @@ -69,10 +72,12 @@ pub enum Kind { Pedal, /// Stream Deck Plus Plus, - /// Ajazz Stream Deck AKP153 + /// Ajazz AKP153 Desk Controller Akp153, - /// Ajazz Stream Deck AKP153E + /// Ajazz AKP153E Desk Controller Akp153E, + /// Ajazz Akl982 Desk Controller + Akp815, } impl Kind { @@ -96,6 +101,7 @@ impl Kind { AJAZZ_VENDOR_ID_1 | AJAZZ_VENDOR_ID_2 => match pid { PID_AJAZZ_AKP153 => Some(Kind::Akp153), PID_AJAZZ_E_AKP153E => Some(Kind::Akp153E), + PID_AJAZZ_AKP815 => Some(Kind::Akp815), _ => None } @@ -117,6 +123,7 @@ impl Kind { Kind::Pedal => PID_STREAMDECK_PEDAL, Kind::Plus => PID_STREAMDECK_PLUS, Kind::Akp153 => PID_AJAZZ_AKP153, + Kind::Akp815 => PID_AJAZZ_AKP815, Kind::Akp153E => PID_AJAZZ_E_AKP153E, } } @@ -135,6 +142,7 @@ impl Kind { Kind::Pedal => ELGATO_VENDOR_ID, Kind::Plus => ELGATO_VENDOR_ID, Kind::Akp153 => AJAZZ_VENDOR_ID_1, + Kind::Akp815 => AJAZZ_VENDOR_ID_1, Kind::Akp153E => AJAZZ_VENDOR_ID_2, } } @@ -148,6 +156,7 @@ impl Kind { Kind::Pedal => 3, Kind::Neo | Kind::Plus => 8, Kind::Akp153 | Kind::Akp153E => 15 + 3, + Kind::Akp815 => 15, } } @@ -160,6 +169,7 @@ impl Kind { Kind::Pedal => 1, Kind::Neo | Kind::Plus => 2, Kind::Akp153 | Kind::Akp153E => 3, + Kind::Akp815 =>5, } } @@ -171,8 +181,8 @@ impl Kind { Kind::Xl | Kind::XlV2 => 8, Kind::Pedal => 3, Kind::Neo | Kind::Plus => 4, - Kind::Akp153 => 6, - Kind::Akp153E => 6, + Kind::Akp153 | Kind::Akp153E => 6, + Kind::Akp815 => 3, } } @@ -197,7 +207,8 @@ impl Kind { match self { Kind::Plus => Some((800, 100)), Kind::Neo => Some((248, 58)), - Kind::Akp153 | Kind::Akp153E => Some((854, 480)), // logo + Kind::Akp153 | Kind::Akp153E => Some((854, 480)), + Kind::Akp815 => Some((800, 480)), _ => None, } } @@ -261,6 +272,13 @@ impl Kind { rotation: ImageRotation::Rot90, mirror: ImageMirroring::Both, }, + + Kind::Akp815 => ImageFormat { + mode: ImageMode::JPEG, + size: (100, 100), + rotation: ImageRotation::Rot180, + mirror: ImageMirroring::None, + }, } } diff --git a/src/lib.rs b/src/lib.rs index 74cae62..3a005bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,9 +22,7 @@ use hidapi::{HidApi, HidDevice, HidError, HidResult}; use image::{DynamicImage, ImageError}; use crate::info::{is_vendor_familiar, Kind}; -use crate::util::{ - 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, -}; +use crate::util::{ajazz153_to_elgato_input, elgato153_to_ajazz, extract_str, flip_key_index, get_feature_report, inverse_key_index, 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; @@ -158,7 +156,7 @@ impl StreamDeck { /// Returns serial number of the device pub fn serial_number(&self) -> Result { match self.kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let serial = self.device.get_serial_number_string()?; match serial { Some(serial) => { @@ -197,7 +195,7 @@ impl StreamDeck { Ok(extract_str(&bytes[5..])?) } - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let bytes = get_feature_report(&self.device, 0x01, 20)?; Ok(extract_str(&bytes[0..])?) } @@ -216,11 +214,14 @@ impl StreamDeck { } self.initialized.store(true, Ordering::Release); match self.kind { - Kind::Akp153 | Kind::Akp153E => { - // CRT\x00\x00DIS + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { + let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x44, 0x49, 0x53]; + buf.extend(vec![0u8; 512 - buf.len()]); + write_data(&self.device, buf.as_slice())?; + 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())?; + write_data(&self.device, buf.as_slice())?; } _ => { @@ -251,7 +252,7 @@ impl StreamDeck { } } - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let data = match self.kind { _ => read_data(&self.device, 512, timeout), }?; @@ -264,7 +265,11 @@ impl StreamDeck { 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); + let key = if self.kind == Kind::Akp815 { + inverse_key_index(&self.kind, data[9] - 1) + } else { + ajazz153_to_elgato_input(&self.kind, data[9] - 1) + }; states[(key + 1) as usize] = 0x1u8; } @@ -299,7 +304,7 @@ impl StreamDeck { Ok(send_feature_report(&self.device, buf.as_slice())?) } - Kind::Akp153 | Kind::Akp153E => Ok({ + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => Ok({ self.set_brightness(100)?; self.clear_button_image(0xff)?; }), @@ -328,7 +333,7 @@ impl StreamDeck { Ok(send_feature_report(&self.device, buf.as_slice())?) } - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x00, 0x00, percent]; buf.extend(vec![0u8; 512 - buf.len()]); @@ -356,7 +361,9 @@ impl StreamDeck { let key = if let Kind::Original = self.kind { flip_key_index(&self.kind, key) } else if let Kind::Akp153 | Kind::Akp153E = self.kind { - elgato_to_ajazz(&self.kind, key) + elgato153_to_ajazz(&self.kind, key) + } else if let Kind::Akp815 = self.kind { + inverse_key_index(&self.kind, key) } else { key }; @@ -366,7 +373,7 @@ impl StreamDeck { } match self.kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let mut buf = vec![ 0x43, 0x52, @@ -434,8 +441,8 @@ impl StreamDeck { 0, ], - Kind::Akp153 | Kind::Akp153E => vec![], - + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => vec![], + _ => vec![ 0x02, 0x07, @@ -573,8 +580,12 @@ impl StreamDeck { pub fn clear_button_image(&self, key: u8) -> Result<(), StreamDeckError> { self.initialize()?; match self.kind { - Kind::Akp153 | Kind::Akp153E => { - let key = elgato_to_ajazz(&self.kind, key); + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { + let key = if self.kind == Kind::Akp815 { + inverse_key_index(&self.kind, key) + } else { + elgato153_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 }]; @@ -594,7 +605,7 @@ impl StreamDeck { pub fn clear_all_button_images(&self) -> Result<(), StreamDeckError> { self.initialize()?; match self.kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { self.clear_button_image(0xff) } _ => { @@ -618,7 +629,7 @@ impl StreamDeck { pub fn set_logo_image(&self, image: DynamicImage) -> Result<(), StreamDeckError> { self.initialize()?; match self.kind { - Kind::Akp153 | Kind::Akp153E => (), + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => (), _ => { return Err(StreamDeckError::UnsupportedOperation) } @@ -695,13 +706,13 @@ impl StreamDeck { let image_report_length = match self.kind { Kind::Original => 8191, - Kind::Akp153 | Kind::Akp153E => 512, + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => 512, _ => 1024, }; let image_report_header_length = match self.kind { Kind::Original | Kind::Mini | Kind::MiniMk2 => 16, - Kind::Akp153 | Kind::Akp153E => 0, + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => 0, _ => 8, }; @@ -754,7 +765,7 @@ impl StreamDeck { pub fn sleep(&self) -> Result<(), StreamDeckError> { self.initialize()?; match self.kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x48, 0x41, 0x4e]; buf.extend(vec![0u8; 512 - buf.len()]); @@ -768,27 +779,32 @@ impl StreamDeck { } } + /// Make periodic events to the device, to keep it alive + pub fn keep_alive(&self) -> Result<(), StreamDeckError> { + self.initialize()?; + match self.kind { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { + let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54]; + buf.extend(vec![0u8; 512 - buf.len()]); + write_data(&self.device, buf.as_slice())?; + Ok(()) + } + + _ => Err(StreamDeckError::UnsupportedOperation), + } + } + /// Shutdown the device pub fn shutdown(&self) -> Result<(), StreamDeckError> { self.initialize()?; 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())?; - - 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())?; - + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { 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())?; + 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(()) @@ -811,7 +827,7 @@ impl StreamDeck { } match self.kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let mut buf = vec![0x43, 0x52, 0x54, 0x00, 0x00, 0x53, 0x54, 0x50]; buf.extend(vec![0u8; 512 - buf.len()]); @@ -885,13 +901,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 | Kind::Akp153E => 512, + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => 512, _ => 1024, }; let image_report_header_length = match kind { Kind::Original | Kind::Mini | Kind::MiniMk2 => 16, - Kind::Akp153 | Kind::Akp153E => 0, + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => 0, _ => 8, }; @@ -1044,7 +1060,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::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { if *their { updates.push(DeviceStateUpdate::ButtonDown(index as u8)); updates.push(DeviceStateUpdate::ButtonUp(index as u8)); diff --git a/src/util.rs b/src/util.rs index 17ffd83..ebae50b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -65,14 +65,6 @@ pub fn extract_str(bytes: &[u8]) -> Result { } /* - 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 | @@ -81,30 +73,62 @@ pub fn extract_str(bytes: &[u8]) -> Result { |----|----|----|----|----|----| | 13 | 14 | 15 | 16 | 17 | 18 | ----------------------------- + + Ajazz's AKP153(E) key index + ----------------------------- +| 0d | 0a | 07 | 04 | 01 | 10 | +|----|----|----|----|----|----| +| 0e | 0b | 08 | 05 | 02 | 11 | +|----|----|----|----|----|----| +| 0f | 0c | 09 | 06 | 03 | 12 | + ----------------------------- + + Ajazz's AKP815 key index + -------------- + | 0f | 0e | 0d | + |----|----|----| + | 0c | 0b | 0a | + |----|----|----| + | 09 | 08 | 07 | + |----|----|----| + | 06 | 05 | 04 | + |----|----|----| + | 03 | 02 | 01 | + -------------- + */ /// Converts Elgato key index to Ajazz key index -pub fn elgato_to_ajazz(kind: &Kind, key: u8) -> u8 { +pub fn elgato153_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]; + [12, 9, 6, 3, 0, 15, 13, 10, 7, 4, 1, 16, 14, 11, 8, 5, 2, 17][key as usize] } else { - return key; + key } } /// Converts Ajazz key index to Elgato key index -pub fn ajazz_to_elgato_input(kind: &Kind, key: u8) -> u8 { +pub fn ajazz153_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]; + [4, 10, 16, 3, 9, 15, 2, 8, 14, 1, 7, 13, 0, 6, 12, 5, 11, 17][key as usize] } else { - return key; + key + } +} + +/// Make last key index first, and first key index last +pub fn inverse_key_index(kind: &Kind, key: u8) -> u8 { + if key < kind.key_count() { + kind.key_count() - 1 - key + } else { + 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(); - return (key - col) + ((kind.column_count() - 1) - col); + (key - col) + ((kind.column_count() - 1) - col) } /// Reads button states, empty vector if no data @@ -114,7 +138,7 @@ pub fn read_button_states(kind: &Kind, states: &Vec) -> Vec { } match kind { - Kind::Akp153 | Kind::Akp153E => { + Kind::Akp153 | Kind::Akp153E | Kind::Akp815 => { let mut bools = vec![]; for i in 0..kind.key_count() {