Initial commit
This commit is contained in:
commit
023283b807
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
125
Cargo.lock
generated
Normal file
125
Cargo.lock
generated
Normal file
@ -0,0 +1,125 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e1e6fb1c9e3d6fcdec57216a74eaa03e41f52a22f13a16438251d8e88b89da"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
|
||||
|
||||
[[package]]
|
||||
name = "keyboard_control_software"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"json",
|
||||
"libusb",
|
||||
]
|
||||
|
||||
[[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.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "libusb"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f990ddd929cbe53de4ecd6cf26e1f4e0c5b9796e4c629d9046570b03738aa53"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"libc",
|
||||
"libusb-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libusb-sys"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c53b6582563d64ad3e692f54ef95239c3ea8069e82c9eb70ca948869a7ad767"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "keyboard_control_software"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libusb = "0.3.0"
|
||||
colored = "2.0.0"
|
||||
json = "0.12.4"
|
||||
25
numpad_config.json
Normal file
25
numpad_config.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Sebaweb numpad",
|
||||
"vendor_id": "CAFE",
|
||||
"product_id": "53BA",
|
||||
|
||||
"layout": {
|
||||
"rows": 5,
|
||||
"cols": 4,
|
||||
"keys": [
|
||||
["NumLk", "/", "*", "-"],
|
||||
["7", "8", "9", "+"],
|
||||
["4", "5", "6", "&+"],
|
||||
["1", "2", "3", "Enter"],
|
||||
["0", "&0", ",", "&Enter"]
|
||||
]
|
||||
},
|
||||
|
||||
"lighting": {
|
||||
"type": "RGB",
|
||||
"layout": {
|
||||
"rows": 1,
|
||||
"cols": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
131
src/main.rs
Normal file
131
src/main.rs
Normal file
@ -0,0 +1,131 @@
|
||||
extern crate libusb;
|
||||
extern crate colored;
|
||||
extern crate json;
|
||||
|
||||
use colored::Colorize;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct KeyboardLighting {
|
||||
lighting_type: String,
|
||||
rows: u16,
|
||||
cols: u16
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct KeyboardLayout {
|
||||
rows: u16,
|
||||
cols: u16,
|
||||
keys: Vec<String>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct KeyboardConfig {
|
||||
name: String,
|
||||
vendor_id: u16,
|
||||
product_id: u16,
|
||||
layout: KeyboardLayout,
|
||||
lighting: KeyboardLighting
|
||||
}
|
||||
|
||||
fn parse_config(config_path: &Path) -> KeyboardConfig{
|
||||
let mut parsed_json = json::parse(&std::fs::read_to_string(config_path).unwrap()).unwrap();
|
||||
|
||||
// General info
|
||||
let extracted_name: String = parsed_json["name"].as_str().expect("ERROR: Failed to parse name").to_string();
|
||||
let extracted_vendor_id: u16 = u16::from_str_radix(parsed_json["vendor_id"].as_str().expect("ERROR: Failed to parse name"), 16).unwrap();
|
||||
let extracted_product_id: u16 = u16::from_str_radix(parsed_json["product_id"].as_str().expect("ERROR: Failed to parse name"), 16).unwrap();
|
||||
|
||||
// Layout
|
||||
let extracted_layout_rows: u16 = parsed_json["layout"]["rows"].as_u16().expect("ERROR: Failed to parse layout rows");
|
||||
let extracted_layout_cols: u16 = parsed_json["layout"]["cols"].as_u16().expect("ERROR: Failed to parse layout cols");
|
||||
let mut extracted_layout_keys: Vec<String> = Vec::new();
|
||||
let mut keys: std::collections::VecDeque<String> = std::collections::VecDeque::new();
|
||||
for i in 0..extracted_layout_rows {
|
||||
let mut row: json::JsonValue = parsed_json["layout"]["keys"].pop();
|
||||
for j in 0..extracted_layout_cols {
|
||||
keys.push_front(row.pop().as_str().expect("ERROR: Failed to extract key names").to_string());
|
||||
}
|
||||
}
|
||||
for i in 0..keys.len() {
|
||||
extracted_layout_keys.push(keys.pop_front().expect("ERROR: Empty key value"));
|
||||
}
|
||||
|
||||
let keyboard_layout = KeyboardLayout {
|
||||
rows: extracted_layout_rows,
|
||||
cols: extracted_layout_cols,
|
||||
keys: extracted_layout_keys
|
||||
};
|
||||
|
||||
// Lighting
|
||||
let extracted_lighting_type: String = parsed_json["lighting"]["type"].as_str().expect("ERROR: Failed to parse lighting type").to_string();
|
||||
let extracted_lighting_rows: u16 = parsed_json["lighting"]["layout"]["rows"].as_u16().expect("ERROR: Failed to parse lighting rows");
|
||||
let extracted_lighting_cols: u16 = parsed_json["lighting"]["layout"]["cols"].as_u16().expect("ERROR: Failed to parse lighting cols");
|
||||
|
||||
let keyboard_lighting = KeyboardLighting {
|
||||
lighting_type: extracted_lighting_type,
|
||||
rows: extracted_lighting_rows,
|
||||
cols: extracted_lighting_cols
|
||||
};
|
||||
|
||||
|
||||
let keyboard_config = KeyboardConfig {
|
||||
name: extracted_name,
|
||||
vendor_id: extracted_vendor_id,
|
||||
product_id: extracted_product_id,
|
||||
layout: keyboard_layout,
|
||||
lighting: keyboard_lighting
|
||||
};
|
||||
|
||||
return keyboard_config;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config: KeyboardConfig = parse_config(&Path::new("numpad_config.json"));
|
||||
|
||||
println!("{:#?}", config);
|
||||
|
||||
let context = libusb::Context::new().unwrap();
|
||||
|
||||
for device in context.devices().unwrap().iter() {
|
||||
let device_desc = device.device_descriptor().unwrap();
|
||||
|
||||
println!("Bus {:03} Device {:03} ID {:04x}:{:04x}",
|
||||
device.bus_number(),
|
||||
device.address(),
|
||||
device_desc.vendor_id(),
|
||||
device_desc.product_id());
|
||||
|
||||
|
||||
if device_desc.vendor_id() == config.vendor_id && device_desc.product_id() == config.product_id {
|
||||
println!("Woah, this is my device! I'm going to open it!");
|
||||
let config_desc = device.active_config_descriptor().unwrap();
|
||||
|
||||
let mut device_handle: libusb::DeviceHandle = device.open().unwrap();
|
||||
println!("Number of interfaces: {}", config_desc.num_interfaces());
|
||||
//println!("The device supports these languages: {:?}", &device_handle.read_languages(std::time::Duration::from_millis(100)));
|
||||
|
||||
if device_handle.kernel_driver_active(0).unwrap() {
|
||||
println!("Interface has kernel driver, detaching...");
|
||||
device_handle.detach_kernel_driver(0).unwrap();
|
||||
}
|
||||
device_handle.claim_interface(0).unwrap();
|
||||
|
||||
match device_handle.write_control(libusb::request_type(libusb::Direction::Out, libusb::RequestType::Class, libusb::Recipient::Interface), 0x09, 0x0300, 0, &[0x00], std::time::Duration::from_secs(1)) {
|
||||
Ok(n) => {
|
||||
println!("{}", format!("Successfully wrote {} bytes!", n).green());
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("{}{:?}", format!("Failed to write with error: ").red().bold(), e);
|
||||
}
|
||||
}
|
||||
|
||||
device_handle.release_interface(0).unwrap();
|
||||
device_handle.attach_kernel_driver(0).unwrap();
|
||||
|
||||
println!("Goodbye!");
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user