add keyboard-state program

This commit is contained in:
xunuwu 2025-06-17 20:00:01 +02:00
parent f4fcb11512
commit 5d4ba8fbab
Signed by: xun
SSH key fingerprint: SHA256:Uot/1WoAjWAeqLOHA5vYy4phhVydsH7jCPmBjaPZfgI
6 changed files with 308 additions and 0 deletions

View file

@ -4,5 +4,6 @@
krunker = pkgs.callPackage ./krunker {};
ida-pro = pkgs.callPackage ./ida-pro {};
cartograph-cf = pkgs.callPackage ./cartograph-cf {};
keyboard-state = pkgs.callPackage ./keyboard-state {};
};
}

View file

@ -0,0 +1,17 @@
{
rustPlatform,
pkg-config,
udev,
}:
rustPlatform.buildRustPackage {
pname = "keyboard-state";
version = "0.1.0";
src = ./source;
cargoLock.lockFile = ./source/Cargo.lock;
nativeBuildInputs = [pkg-config];
buildInputs = [udev];
meta.mainProgram = "keyboard-state";
}

1
pkgs/keyboard-state/source/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

185
pkgs/keyboard-state/source/Cargo.lock generated Normal file
View file

@ -0,0 +1,185 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "cc"
version = "1.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "enumflags2"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
dependencies = [
"enumflags2_derive",
]
[[package]]
name = "enumflags2_derive"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "hidapi"
version = "2.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b876ecf37e86b359573c16c8366bc3eba52b689884a0fc42ba3f67203d2a8b"
dependencies = [
"cc",
"cfg-if",
"libc",
"pkg-config",
"windows-sys",
]
[[package]]
name = "keyboard-state"
version = "0.1.0"
dependencies = [
"anyhow",
"enumflags2",
"hidapi",
]
[[package]]
name = "libc"
version = "0.2.173"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
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",
]
[[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_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[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_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[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_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

View file

@ -0,0 +1,9 @@
[package]
name = "keyboard-state"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.98"
enumflags2 = "0.7.12"
hidapi = "2.6.3"

View file

@ -0,0 +1,95 @@
use std::thread;
use std::time::Duration;
use enumflags2::{BitFlag, bitflags};
use hidapi::{HidApi, HidDevice, HidResult};
const VENDOR_ID: u16 = 0x594d;
const PRODUCT_ID: u16 = 0x0075;
const USAGE_PAGE: u16 = 0xFF60;
const USAGE: u16 = 0x61;
#[bitflags]
#[repr(u16)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Layer {
Base = 1 << 0,
Gaming = 1 << 1,
More = 1 << 2,
Extra = 1 << 3,
}
fn main() -> anyhow::Result<()> {
let mut api = HidApi::new()?;
let mut device: Option<HidDevice> = None;
loop {
match &device {
Some(d) => {
let mut data = [0u8; 32];
if d.read(&mut data).is_err() {
eprintln!("Device disconnected. Searching for device...");
device = None;
} else {
let layers = Layer::from_bits_truncate(u16::from_le_bytes([data[0], data[1]]));
let short_layers: String = layers
.iter()
.map(|x| match x {
Layer::Base => "B",
Layer::Gaming => "G",
Layer::More => "m",
Layer::Extra => "e",
})
.collect();
let long_layers: String = layers
.iter()
.map(|x| match x {
Layer::Base => "Base",
Layer::Gaming => "Gaming",
Layer::More => "more",
Layer::Extra => "extra",
})
.flat_map(|elem| [", ", elem])
.skip(1)
.collect();
println!(
r#"{{"text":"{short_layers}", "alt": "none", "tooltip": "{long_layers}", "class": "none"}}"#
);
}
}
None => {
api.reset_devices()?;
api.add_devices(VENDOR_ID, PRODUCT_ID)?;
println!(
r#"{{"text":"N/A", "alt": "Unknown keyboard state", "tooltip": "none", "class": "none"}}"#
);
match api.device_list().find(|device| {
device.vendor_id() == VENDOR_ID
&& device.product_id() == PRODUCT_ID
&& device.usage_page() == USAGE_PAGE
&& device.usage() == USAGE
}) {
Some(d) => match api.open_path(d.path()) {
Ok(d) => {
eprintln!("Device connected");
device = Some(d)
}
Err(e) => {
eprintln!("Error connecting to device: {e}");
thread::sleep(Duration::from_secs(2));
}
},
None => {
thread::sleep(Duration::from_secs(2));
}
}
}
}
}
}