use crate::{
led::LedReport,
translate::Translated,
usb::{
hid::{
HidDevice,
Protocol,
ReportType,
Subclass,
},
report::Reporter,
},
};
pub struct Keyboard<L> {
reporter: Reporter,
boot: bool,
leds: L,
}
impl<L> Keyboard<L> {
pub fn new(leds: L, reporter: Reporter) -> Keyboard<L> {
Keyboard {
leds,
reporter,
boot: false,
}
}
pub fn update_report(&mut self, keystroke: Translated) {
self.reporter.update_report(keystroke)
}
}
impl<L> HidDevice for Keyboard<L>
where
L: LedReport,
{
fn subclass(&self) -> Subclass {
Subclass::BootInterface
}
fn protocol(&self) -> Protocol {
Protocol::Keyboard
}
fn report_descriptor(&self) -> &[u8] {
if self.boot {
self.reporter.get_boot_desc()
} else {
self.reporter.get_desc()
}
}
fn get_report(
&mut self,
report_type: ReportType,
_report_id: u8,
) -> Result<&[u8], &'static str> {
match report_type {
ReportType::Input => Ok(if self.boot {
self.reporter.get_boot_report()
} else {
self.reporter.get_report()
}),
_ => Err("unsupprted report type"),
}
}
fn set_boot(&mut self, boot: bool) {
self.boot = boot;
}
fn set_report(
&mut self,
report_type: ReportType,
report_id: u8,
data: &[u8],
) -> Result<(), &'static str> {
if report_type == ReportType::Output && report_id == 0 && data.len() == 1 {
self.leds.from_report_byte(data[0]);
return Ok(());
}
Err("invalid set_report request")
}
}