use crate::common;
use crate::keymap;
use crate::protocol;
use anyhow::Result;
use crossterm::cursor;
use hidapi::{DeviceInfo, HidApi};
use std::collections::HashMap;
use std::io;
use std::io::Write;
use std::{thread, time};
pub fn run(api: &HidApi, device: &DeviceInfo, unlock: bool, lock: bool) -> Result<()> {
let device_path = device.path();
let dev = api.open_path(device_path)?;
let capabilities = protocol::scan_capabilities(&dev)?;
let meta = common::load_meta(&dev, &capabilities, &None)?;
if capabilities.vial_version == 0 {
println!("Device doesn't support locking");
} else {
let mut status = protocol::get_locked_status(&dev)?;
println!("Device is locked: {}", status.locked);
if status.locked && unlock {
println!("Starting unlock process... ");
println!("Push marked buttons and keep then pushed to unlock...");
let layout_options = &meta["layouts"]["labels"];
let state = protocol::load_layout_options(&dev)?;
let options = protocol::LayoutOptions::from_json(state, layout_options)?;
let mut buttons = keymap::keymap_to_buttons(&meta["layouts"]["keymap"], &options)?;
let mut button_labels = HashMap::new();
for (row, col) in &status.unlock_buttons {
button_labels.insert((*row, *col), "☆☆,☆☆".to_string());
}
for button in &mut buttons {
button.color = if status
.unlock_buttons
.contains(&(button.wire_x, button.wire_y))
{
Some((255, 255, 255))
} else {
None
};
}
keymap::render_and_dump(&buttons, Some(button_labels));
if !status.unlock_in_progress {
protocol::start_unlock(&dev)?;
}
let sleep_duration = time::Duration::from_millis(100);
let mut unlocked = false;
let mut polls_remaining: u8;
while !unlocked {
thread::sleep(sleep_duration);
(unlocked, polls_remaining) = protocol::unlock_poll(&dev)?;
print!("{}", cursor::MoveToColumn(0));
print!(
"Seconds remaining: {} keep pushing...",
(polls_remaining as f64) / 10.0
);
io::stdout().flush()?;
}
status = protocol::get_locked_status(&dev)?;
println!("\nDevice is locked: {}", status.locked);
} else if !status.locked && lock {
println!("Locking keyboard...");
protocol::set_locked(&dev)?;
status = protocol::get_locked_status(&dev)?;
println!("Device is locked: {}", status.locked);
}
}
Ok(())
}