summary refs log tree commit diff stats
path: root/rust/qmk-hid-com/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rust/qmk-hid-com/src/main.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/rust/qmk-hid-com/src/main.rs b/rust/qmk-hid-com/src/main.rs
new file mode 100644
index 0000000..ebaa91b
--- /dev/null
+++ b/rust/qmk-hid-com/src/main.rs
@@ -0,0 +1,107 @@
+// Qmk Hid Com - A small middelware between a qmk keyboard and a wayland virtual
+// keyboard. For unicode input
+//
+// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: AGPL-3.0-or-later
+//
+// This file is part of Qmk Hid Com.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/agpl.txt>.
+
+use clap::Parser;
+use cli::{CliArgs, Command, Inform};
+
+mod cli;
+mod hid;
+mod search;
+
+fn main() -> anyhow::Result<()> {
+    let args = CliArgs::parse();
+    let api = hidapi::HidApi::new().unwrap();
+
+    match args.command {
+        Command::Search { vendor_name } => search::search(&api, vendor_name),
+        Command::Monitor {
+            usage_id,
+            usage_page,
+        } => hid::monitor(&api, usage_id, usage_page),
+        Command::Send {
+            usage_id,
+            usage_page,
+            message,
+        } => hid::send(&api, usage_id, usage_page, message),
+
+        Command::Inform { command } => {
+            let (decimal, _) = match command {
+                Inform::Hex { val } => (i64::from_str_radix(&val.to_lowercase(), 16)?, val),
+                Inform::Dec { val } => (val, val.to_string()),
+                Inform::Bin { val } => (i64::from_str_radix(&val.to_lowercase(), 2)?, val),
+                Inform::Char { val } => ((val as u32) as i64, val.to_string()),
+            };
+
+            let character = char::from_u32(decimal as u32).unwrap();
+
+            let binary = {
+                decimal
+                    .to_ne_bytes()
+                    .map(|sm| format!("{:<08b}", sm))
+                    .join(" ")
+            };
+
+            let split = {
+                let first;
+                let second;
+                let third;
+                let fourth;
+
+                if cfg!(target_endian = "big") {
+                    let decimal: u32 = decimal as u32;
+                    let decimal = decimal.to_be();
+
+                    dbg!(decimal
+                        .to_be_bytes()
+                        .map(|sm| format!("{:<08b}", sm))
+                        .join(" "));
+
+                    fourth = decimal as u8;
+                    third = (decimal >> 8) as u8;
+                    second = (decimal >> 16) as u8;
+                    first = (decimal >> 24) as u8;
+                } else {
+                    first = decimal as u8;
+                    second = (decimal >> 8) as u8;
+                    third = (decimal >> 16) as u8;
+                    fourth = (decimal >> 24) as u8;
+                }
+                [first, second, third, fourth]
+            };
+
+            println!(
+                "dec: {}, hex: {:x}, char: {:#?}, bin: {}, split: {:?}/[{}] ({})",
+                decimal,
+                decimal,
+                character,
+                binary,
+                split,
+                split
+                    .iter()
+                    .map(|val| format!("{:x}", val))
+                    .collect::<Vec<_>>()
+                    .join(", "),
+                i32::from_ne_bytes(split)
+            );
+            Ok(())
+        }
+        Command::ArrInform { values } => {
+            assert_eq!(values.len(), 4);
+            let arr = [values[0], values[1], values[2], values[3]];
+
+            let output = u32::from_le_bytes(arr);
+
+            println!("{:?} -> {output}", arr);
+
+            Ok(())
+        }
+    }
+}