summaryrefslogtreecommitdiffstats
path: root/rsnix/src/ps2.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/ps2.rs')
-rw-r--r--rsnix/src/ps2.rs31
1 files changed, 20 insertions, 11 deletions
diff --git a/rsnix/src/ps2.rs b/rsnix/src/ps2.rs
index 1b10b3b..8dd58a0 100644
--- a/rsnix/src/ps2.rs
+++ b/rsnix/src/ps2.rs
@@ -22,8 +22,10 @@ pub enum KeyEvent {
22 Backspace, 22 Backspace,
23 Tab, 23 Tab,
24 Escape, 24 Escape,
25 CtrlC, 25 /// Ctrl + key (e.g. Ctrl('c') = ^C, Ctrl('s') = ^S).
26 CtrlD, 26 Ctrl(char),
27 /// Ctrl + arrow (0=up, 1=down, 2=left, 3=right) — word/page nav.
28 CtrlArrow(u8),
27 ArrowUp, 29 ArrowUp,
28 ArrowDown, 30 ArrowDown,
29 ArrowLeft, 31 ArrowLeft,
@@ -306,13 +308,14 @@ fn process_byte(byte: u8) -> Option<KeyEvent> {
306 ch.to_ascii_uppercase() 308 ch.to_ascii_uppercase()
307 }; 309 };
308 } 310 }
309 // Ctrl+letter — the shell uses ^C (interrupt) and ^D (EOF). 311 // Ctrl+key — the terminal control-byte protocol (^C, ^D, ^S, ^X, …).
310 let ctrl = state.modifiers & (MOD_LCTRL | MOD_RCTRL) != 0; 312 let ctrl = state.modifiers & (MOD_LCTRL | MOD_RCTRL) != 0;
311 if ctrl { 313 if ctrl {
312 return match ch.to_ascii_lowercase() { 314 let lc = ch.to_ascii_lowercase();
313 b'c' => Some(KeyEvent::CtrlC), 315 return if lc.is_ascii_graphic() {
314 b'd' => Some(KeyEvent::CtrlD), 316 Some(KeyEvent::Ctrl(lc as char))
315 _ => None, // swallow other Ctrl+key combinations 317 } else {
318 None // swallow non-graphic Ctrl combos
316 }; 319 };
317 } 320 }
318 if ch != 0 { 321 if ch != 0 {
@@ -334,10 +337,10 @@ fn process_e0(byte: u8) -> Option<KeyEvent> {
334 update_modifiers(byte, true, true); 337 update_modifiers(byte, true, true);
335 338
336 match byte { 339 match byte {
337 0x48 => Some(KeyEvent::ArrowUp), 340 0x48 => Some(if ctrl_held() { KeyEvent::CtrlArrow(0) } else { KeyEvent::ArrowUp }),
338 0x50 => Some(KeyEvent::ArrowDown), 341 0x50 => Some(if ctrl_held() { KeyEvent::CtrlArrow(1) } else { KeyEvent::ArrowDown }),
339 0x4B => Some(KeyEvent::ArrowLeft), 342 0x4B => Some(if ctrl_held() { KeyEvent::CtrlArrow(2) } else { KeyEvent::ArrowLeft }),
340 0x4D => Some(KeyEvent::ArrowRight), 343 0x4D => Some(if ctrl_held() { KeyEvent::CtrlArrow(3) } else { KeyEvent::ArrowRight }),
341 0x47 => Some(KeyEvent::Home), 344 0x47 => Some(KeyEvent::Home),
342 0x4F => Some(KeyEvent::End), 345 0x4F => Some(KeyEvent::End),
343 0x49 => Some(KeyEvent::PageUp), 346 0x49 => Some(KeyEvent::PageUp),
@@ -371,3 +374,9 @@ fn set_mod(state: &mut KbdState, bit: u8, pressed: bool) {
371 state.modifiers &= !bit; 374 state.modifiers &= !bit;
372 } 375 }
373} 376}
377
378/// Is either Ctrl key held?
379fn ctrl_held() -> bool {
380 let state = unsafe { &mut KBD };
381 state.modifiers & (MOD_LCTRL | MOD_RCTRL) != 0
382}