Skip to content

Commit 6c72d80

Browse files
committed
Add a little keyboard test routine.
1 parent ff4c66e commit 6c72d80

File tree

1 file changed

+71
-19
lines changed

1 file changed

+71
-19
lines changed

src/lib.rs

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ static OS_MENU: menu::Menu<Ctx> = menu::Menu {
8181
command: "config",
8282
help: Some("Handle non-volatile OS configuration"),
8383
},
84+
&menu::Item {
85+
item_type: menu::ItemType::Callback {
86+
function: cmd_kbtest,
87+
parameters: &[],
88+
},
89+
command: "kbtest",
90+
help: Some("Test the keyboard (press ESC to quit)"),
91+
},
8492
],
8593
entry: None,
8694
exit: None,
@@ -162,6 +170,7 @@ impl core::fmt::Write for SerialConsole {
162170

163171
struct Ctx {
164172
config: config::Config,
173+
keyboard: pc_keyboard::EventDecoder<pc_keyboard::layouts::AnyLayout>,
165174
}
166175

167176
impl core::fmt::Write for Ctx {
@@ -253,12 +262,14 @@ pub extern "C" fn main(api: *const bios::Api) -> ! {
253262
println!("Welcome to {}!", OS_VERSION);
254263
println!("Copyright © Jonathan 'theJPster' Pallant and the Neotron Developers, 2022");
255264

256-
let ctx = Ctx { config };
265+
let ctx = Ctx {
266+
config,
267+
keyboard: pc_keyboard::EventDecoder::new(
268+
pc_keyboard::layouts::AnyLayout::Uk105Key(pc_keyboard::layouts::Uk105Key),
269+
pc_keyboard::HandleControl::MapLettersToUnicode,
270+
),
271+
};
257272

258-
let mut keyboard = pc_keyboard::EventDecoder::new(
259-
pc_keyboard::layouts::AnyLayout::Uk105Key(pc_keyboard::layouts::Uk105Key),
260-
pc_keyboard::HandleControl::MapLettersToUnicode,
261-
);
262273
let mut buffer = [0u8; 256];
263274
let mut menu = menu::Runner::new(&OS_MENU, &mut buffer, ctx);
264275

@@ -270,7 +281,7 @@ pub extern "C" fn main(api: *const bios::Api) -> ! {
270281
state: pc_keyboard::KeyState::Down,
271282
};
272283
if let Some(pc_keyboard::DecodedKey::Unicode(mut ch)) =
273-
keyboard.process_keyevent(pckb_ev)
284+
menu.context.keyboard.process_keyevent(pckb_ev)
274285
{
275286
if ch == '\n' {
276287
ch = '\r';
@@ -288,7 +299,7 @@ pub extern "C" fn main(api: *const bios::Api) -> ! {
288299
state: pc_keyboard::KeyState::Up,
289300
};
290301
if let Some(pc_keyboard::DecodedKey::Unicode(ch)) =
291-
keyboard.process_keyevent(pckb_ev)
302+
menu.context.keyboard.process_keyevent(pckb_ev)
292303
{
293304
let mut buffer = [0u8; 6];
294305
let s = ch.encode_utf8(&mut buffer);
@@ -310,7 +321,7 @@ pub extern "C" fn main(api: *const bios::Api) -> ! {
310321
}
311322

312323
/// Called when the "lshw" command is executed.
313-
fn cmd_lshw(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _context: &mut Ctx) {
324+
fn cmd_lshw(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
314325
let api = API.get();
315326
let mut found = false;
316327

@@ -397,14 +408,14 @@ fn cmd_lshw(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _c
397408
}
398409

399410
/// Called when the "clear" command is executed.
400-
fn cmd_clear(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _context: &mut Ctx) {
411+
fn cmd_clear(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
401412
if let Some(ref mut console) = unsafe { &mut VGA_CONSOLE } {
402413
console.clear();
403414
}
404415
}
405416

406417
/// Called when the "fill" command is executed.
407-
fn cmd_fill(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _context: &mut Ctx) {
418+
fn cmd_fill(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &mut Ctx) {
408419
if let Some(ref mut console) = unsafe { &mut VGA_CONSOLE } {
409420
console.clear();
410421
}
@@ -425,19 +436,19 @@ fn cmd_fill(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _c
425436
}
426437

427438
/// Called when the "config" command is executed.
428-
fn cmd_config(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], context: &mut Ctx) {
439+
fn cmd_config(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], ctx: &mut Ctx) {
429440
let command = args.get(0).cloned().unwrap_or("print");
430441
match command {
431442
"reset" => match config::Config::load() {
432443
Ok(new_config) => {
433-
context.config = new_config;
444+
ctx.config = new_config;
434445
println!("Loaded OK.");
435446
}
436447
Err(e) => {
437448
println!("Error loading; {}", e);
438449
}
439450
},
440-
"save" => match context.config.save() {
451+
"save" => match ctx.config.save() {
441452
Ok(_) => {
442453
println!("Saved OK.");
443454
}
@@ -447,11 +458,11 @@ fn cmd_config(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], c
447458
},
448459
"vga" => match args.get(1).cloned() {
449460
Some("on") => {
450-
context.config.set_vga_console(true);
461+
ctx.config.set_vga_console(true);
451462
println!("VGA now on");
452463
}
453464
Some("off") => {
454-
context.config.set_vga_console(false);
465+
ctx.config.set_vga_console(false);
455466
println!("VGA now off");
456467
}
457468
_ => {
@@ -461,19 +472,19 @@ fn cmd_config(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], c
461472
"serial" => match (args.get(1).cloned(), args.get(1).map(|s| s.parse::<u32>())) {
462473
(_, Some(Ok(baud))) => {
463474
println!("Turning serial console on at {} bps", baud);
464-
context.config.set_serial_console_on(baud);
475+
ctx.config.set_serial_console_on(baud);
465476
}
466477
(Some("off"), _) => {
467478
println!("Turning serial console off");
468-
context.config.set_serial_console_off();
479+
ctx.config.set_serial_console_off();
469480
}
470481
_ => {
471482
println!("Give off or an integer as argument");
472483
}
473484
},
474485
"print" => {
475-
println!("VGA : {}", context.config.get_vga_console());
476-
match context.config.get_serial_console() {
486+
println!("VGA : {}", ctx.config.get_vga_console());
487+
match ctx.config.get_serial_console() {
477488
None => {
478489
println!("Serial: off");
479490
}
@@ -495,6 +506,47 @@ fn cmd_config(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], c
495506
}
496507
}
497508

509+
/// Called when the "kbtest" command is executed.
510+
fn cmd_kbtest(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], ctx: &mut Ctx) {
511+
let api = API.get();
512+
loop {
513+
match (api.hid_get_event)() {
514+
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::KeyPress(code))) => {
515+
let pckb_ev = pc_keyboard::KeyEvent {
516+
code,
517+
state: pc_keyboard::KeyState::Down,
518+
};
519+
if let Some(ev) = ctx.keyboard.process_keyevent(pckb_ev) {
520+
println!("Code={code:?} State=Down Decoded={ev:?}");
521+
} else {
522+
println!("Code={code:?} State=Down Decoded=None");
523+
}
524+
if code == pc_keyboard::KeyCode::Escape {
525+
break;
526+
}
527+
}
528+
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::KeyRelease(code))) => {
529+
let pckb_ev = pc_keyboard::KeyEvent {
530+
code,
531+
state: pc_keyboard::KeyState::Up,
532+
};
533+
if let Some(ev) = ctx.keyboard.process_keyevent(pckb_ev) {
534+
println!("Code={code:?} State=Up Decoded={ev:?}");
535+
} else {
536+
println!("Code={code:?} State=Up Decoded=None");
537+
}
538+
}
539+
bios::Result::Ok(bios::Option::Some(bios::hid::HidEvent::MouseInput(_ignore))) => {}
540+
bios::Result::Ok(bios::Option::None) => {
541+
// Do nothing
542+
}
543+
bios::Result::Err(e) => {
544+
println!("Failed to get HID events: {:?}", e);
545+
}
546+
}
547+
}
548+
}
549+
498550
/// Called when we have a panic.
499551
#[inline(never)]
500552
#[panic_handler]

0 commit comments

Comments
 (0)