Merge pull request 'syscall for getting keymap info' (#7) from feature/nikocs/keymap/syscall into develop
Reviewed-on: #7
This commit is contained in:
		
						commit
						111f16b3b4
					
				
					 5 changed files with 398 additions and 0 deletions
				
			
		
							
								
								
									
										95
									
								
								liblbos/src/keymap.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								liblbos/src/keymap.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,95 @@ | |||
| #[repr(C)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub struct Keymap { | ||||
|     pub alpha: u16, | ||||
|     pub beta: u32, | ||||
|     pub gamma: u16, | ||||
|     pub delta: u16, | ||||
| } | ||||
| 
 | ||||
| #[repr(u16)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum KeymapSection { | ||||
|     Alpha = 1, | ||||
|     Beta = 2, | ||||
|     Gamma = 3, | ||||
|     Delta = 4, | ||||
| } | ||||
| 
 | ||||
| #[repr(u16)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum KeyAlpha { | ||||
|     Esc = 1 << 0, | ||||
|     Key1 = 1 << 1, | ||||
|     Key2 = 1 << 2, | ||||
|     Key3 = 1 << 3, | ||||
|     Key4 = 1 << 4, | ||||
|     Key5 = 1 << 5, | ||||
|     Key6 = 1 << 6, | ||||
|     Key7 = 1 << 7, | ||||
|     Key8 = 1 << 8, | ||||
|     Key9 = 1 << 9, | ||||
|     Key0 = 1 << 10, | ||||
|     Minus = 1 << 11, | ||||
|     Equal = 1 << 12, | ||||
|     Backspace = 1 << 13, | ||||
|     Tab = 1 << 14, | ||||
|     Enter = 1 << 15, | ||||
| } | ||||
| 
 | ||||
| #[repr(u32)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum KeyBeta { | ||||
|     A = 1 << 0, | ||||
|     B = 1 << 1, | ||||
|     C = 1 << 2, | ||||
|     D = 1 << 3, | ||||
|     E = 1 << 4, | ||||
|     F = 1 << 5, | ||||
|     G = 1 << 6, | ||||
|     H = 1 << 7, | ||||
|     I = 1 << 8, | ||||
|     J = 1 << 9, | ||||
|     K = 1 << 10, | ||||
|     L = 1 << 11, | ||||
|     M = 1 << 12, | ||||
|     N = 1 << 13, | ||||
|     O = 1 << 14, | ||||
|     P = 1 << 15, | ||||
|     Q = 1 << 16, | ||||
|     R = 1 << 17, | ||||
|     S = 1 << 18, | ||||
|     T = 1 << 19, | ||||
|     U = 1 << 20, | ||||
|     V = 1 << 21, | ||||
|     W = 1 << 22, | ||||
|     X = 1 << 23, | ||||
|     Y = 1 << 24, | ||||
|     Z = 1 << 25, | ||||
| } | ||||
| 
 | ||||
| #[repr(u16)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum KeyGamma { | ||||
|     LeftBracket = 1 << 0, | ||||
|     RightBracket = 1 << 1, | ||||
|     Semicolon = 1 << 2, | ||||
|     Apostrophe = 1 << 3, | ||||
|     Grave = 1 << 4, | ||||
|     Backslash = 1 << 5, | ||||
|     Comma = 1 << 6, | ||||
|     Dot = 1 << 7, | ||||
|     Slash = 1 << 8, | ||||
|     Space = 1 << 9, | ||||
|     Control = 1 << 10, | ||||
|     Shift = 1 << 11, | ||||
|     Alt = 1 << 12, | ||||
| } | ||||
| 
 | ||||
| #[repr(u16)] | ||||
| pub enum KeyDelta { | ||||
|     UpArrow = 1 << 0, | ||||
|     DownArrow = 1 << 1, | ||||
|     LeftArrow = 1 << 12, | ||||
|     RightArrow = 1 << 13, | ||||
| } | ||||
|  | @ -4,6 +4,7 @@ pub mod fs; | |||
| pub mod ktask; | ||||
| pub mod syscalls; | ||||
| pub mod characters; | ||||
| pub mod keymap; | ||||
| mod arch; | ||||
| 
 | ||||
| #[repr(C)] | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| use crate::arch::{stall, syscall}; | ||||
| use crate::keymap::Keymap; | ||||
| use crate::TaskSetup; | ||||
| 
 | ||||
| #[repr(C)] | ||||
|  | @ -80,6 +81,8 @@ pub enum SysCall { | |||
|     /// flushes changes done within the given rectangle to the framebuffer
 | ||||
|     /// if there is no device providing a gpu, this will not do anything
 | ||||
|     FlushFramebufferRect = 18, | ||||
|     /// fills the given struct with the current keymap info
 | ||||
|     GetCurrentKeymap = 19, | ||||
| 
 | ||||
|     /// doens't return until all other tasks besides the current task and the ktask have exited
 | ||||
|     WaitUntilAlone = 333, | ||||
|  | @ -112,6 +115,7 @@ pub fn usize2sc(u: usize) -> SysCall { | |||
|         16 => SysCall::EnableFramebufferConsole, | ||||
|         17 => SysCall::FramebufferPointer, | ||||
|         18 => SysCall::FlushFramebufferRect, | ||||
|         19 => SysCall::GetCurrentKeymap, | ||||
|         333 => SysCall::WaitUntilAlone, | ||||
|         666 => SysCall::InitKernel, | ||||
|         _ => SysCall::NoAction, | ||||
|  | @ -202,6 +206,10 @@ pub fn flush_framebuffer_rect(x: usize, y: usize, w: usize, h: usize) { | |||
|     syscall(SysCall::FlushFramebufferRect, x, y, w, h, 0, 0); | ||||
| } | ||||
| 
 | ||||
| pub fn get_current_keymap(keymap: &mut Keymap) { | ||||
|     syscall(SysCall::GetCurrentKeymap, keymap as *mut Keymap as usize, 0, 0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| pub fn wait_until_alone() { | ||||
|     syscall(SysCall::WaitUntilAlone, 0, 0, 0, 0, 0, 0); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| use core::sync::atomic::{AtomicBool, Ordering}; | ||||
| use liblbos::keymap::{KeyAlpha, KeyBeta, KeyDelta, KeyGamma, KeymapSection}; | ||||
| use crate::dev::virtio::{ | ||||
|     Descriptor, VIRTIO_DESC_F_WRITE, VIRTIO_MMIO_GUEST_FEATURES, VIRTIO_MMIO_GUEST_PAGE_SIZE, | ||||
|     VIRTIO_MMIO_QUEUE_NUM, VIRTIO_MMIO_QUEUE_NUM_MAX, VIRTIO_MMIO_QUEUE_PFN, VIRTIO_MMIO_QUEUE_SEL, | ||||
|  | @ -187,6 +188,38 @@ impl VirtIoInputDevice { | |||
|                 x if x == VIRTIO_INPUT_EVENT_TYPE_KEYBOARD => { | ||||
|                     let keycode = event.code; | ||||
|                     let down = event.value == 1; | ||||
|                     
 | ||||
|                     // update the TC keymap
 | ||||
|                     { | ||||
|                         let mut keymap = &mut tc.current_keymap; | ||||
|                         if let Some(keycode) = LinuxKeycode::from_u16(keycode) { | ||||
|                             if let Some(alpha) = keycode.to_alpha_key() { | ||||
|                                 if down { | ||||
|                                     keymap.alpha |= alpha as u16; | ||||
|                                 } else { | ||||
|                                     keymap.alpha &= !(alpha as u16); | ||||
|                                 } | ||||
|                             } else if let Some(beta) = keycode.to_beta_key() { | ||||
|                                 if down { | ||||
|                                     keymap.beta |= beta as u32; | ||||
|                                 } else { | ||||
|                                     keymap.beta &= !(beta as u32); | ||||
|                                 } | ||||
|                             } else if let Some(gamma) = keycode.to_gamma_key() { | ||||
|                                 if down { | ||||
|                                     keymap.gamma |= gamma as u16; | ||||
|                                 } else { | ||||
|                                     keymap.gamma &= !(gamma as u16); | ||||
|                                 } | ||||
|                             } else if let Some(delta) = keycode.to_delta_key() { | ||||
|                                 if down { | ||||
|                                     keymap.delta |= delta as u16; | ||||
|                                 } else { | ||||
|                                     keymap.delta &= !(delta as u16); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // first, handle shift todo: handle more control characters
 | ||||
|                     if keycode == LinuxKeycode::LeftShift as u16 || keycode == LinuxKeycode::RightShift as u16 { | ||||
|  | @ -319,6 +352,254 @@ pub enum LinuxKeycode { | |||
|     KP3 = 81, | ||||
|     KP0 = 82, | ||||
|     KPDot = 83, | ||||
|     UpArrow = 103, | ||||
|     DownArrow = 108, | ||||
|     RightArrow = 106, | ||||
|     LeftArrow = 105, | ||||
| } | ||||
| 
 | ||||
| impl LinuxKeycode { | ||||
|     pub fn from_u16(keycode: u16) -> Option<LinuxKeycode> { | ||||
|         const KEYCODES_TO_DOT: &[LinuxKeycode] = &[ | ||||
|             LinuxKeycode::ESC, | ||||
|             LinuxKeycode::Key1, | ||||
|             LinuxKeycode::Key2, | ||||
|             LinuxKeycode::Key3, | ||||
|             LinuxKeycode::Key4, | ||||
|             LinuxKeycode::Key5, | ||||
|             LinuxKeycode::Key6, | ||||
|             LinuxKeycode::Key7, | ||||
|             LinuxKeycode::Key8, | ||||
|             LinuxKeycode::Key9, | ||||
|             LinuxKeycode::Key0, | ||||
|             LinuxKeycode::Minus, | ||||
|             LinuxKeycode::Equal, | ||||
|             LinuxKeycode::Backspace, | ||||
|             LinuxKeycode::Tab, | ||||
|             LinuxKeycode::Q, | ||||
|             LinuxKeycode::W, | ||||
|             LinuxKeycode::E, | ||||
|             LinuxKeycode::R, | ||||
|             LinuxKeycode::T, | ||||
|             LinuxKeycode::Y, | ||||
|             LinuxKeycode::U, | ||||
|             LinuxKeycode::I, | ||||
|             LinuxKeycode::O, | ||||
|             LinuxKeycode::P, | ||||
|             LinuxKeycode::LeftBracket, | ||||
|             LinuxKeycode::RightBracket, | ||||
|             LinuxKeycode::Enter, | ||||
|             LinuxKeycode::LeftControl, | ||||
|             LinuxKeycode::A, | ||||
|             LinuxKeycode::S, | ||||
|             LinuxKeycode::D, | ||||
|             LinuxKeycode::F, | ||||
|             LinuxKeycode::G, | ||||
|             LinuxKeycode::H, | ||||
|             LinuxKeycode::J, | ||||
|             LinuxKeycode::K, | ||||
|             LinuxKeycode::L, | ||||
|             LinuxKeycode::Semicolon, | ||||
|             LinuxKeycode::Apostrophe, | ||||
|             LinuxKeycode::Grave, | ||||
|             LinuxKeycode::LeftShift, | ||||
|             LinuxKeycode::Backslash, | ||||
|             LinuxKeycode::Z, | ||||
|             LinuxKeycode::X, | ||||
|             LinuxKeycode::C, | ||||
|             LinuxKeycode::V, | ||||
|             LinuxKeycode::B, | ||||
|             LinuxKeycode::N, | ||||
|             LinuxKeycode::M, | ||||
|             LinuxKeycode::Comma, | ||||
|             LinuxKeycode::Dot, | ||||
|             LinuxKeycode::Slash, | ||||
|             LinuxKeycode::RightShift, | ||||
|             LinuxKeycode::KPAsterisk, | ||||
|             LinuxKeycode::LeftAlt, | ||||
|             LinuxKeycode::Space, | ||||
|             LinuxKeycode::CapsLock, | ||||
|             LinuxKeycode::F1, | ||||
|             LinuxKeycode::F2, | ||||
|             LinuxKeycode::F3, | ||||
|             LinuxKeycode::F4, | ||||
|             LinuxKeycode::F5, | ||||
|             LinuxKeycode::F6, | ||||
|             LinuxKeycode::F7, | ||||
|             LinuxKeycode::F8, | ||||
|             LinuxKeycode::F9, | ||||
|             LinuxKeycode::F10, | ||||
|             LinuxKeycode::NumLock, | ||||
|             LinuxKeycode::ScrollLock, | ||||
|             LinuxKeycode::KP7, | ||||
|             LinuxKeycode::KP8, | ||||
|             LinuxKeycode::KP9, | ||||
|             LinuxKeycode::KPMinus, | ||||
|             LinuxKeycode::KP4, | ||||
|             LinuxKeycode::KP5, | ||||
|             LinuxKeycode::KP6, | ||||
|             LinuxKeycode::KPPlus, | ||||
|             LinuxKeycode::KP1, | ||||
|             LinuxKeycode::KP2, | ||||
|             LinuxKeycode::KP3, | ||||
|             LinuxKeycode::KP0, | ||||
|             LinuxKeycode::KPDot, | ||||
|         ]; | ||||
|         if keycode > 0 && keycode <= 83 { | ||||
|             let idx = keycode as usize - 1; | ||||
|             Some(KEYCODES_TO_DOT[idx]) | ||||
|         } else if keycode == LinuxKeycode::UpArrow as u16 { | ||||
|             Some(LinuxKeycode::UpArrow) | ||||
|         } else if keycode == LinuxKeycode::DownArrow as u16 { | ||||
|             Some(LinuxKeycode::DownArrow) | ||||
|         } else if keycode == LinuxKeycode::RightArrow as u16 { | ||||
|             Some(LinuxKeycode::RightArrow) | ||||
|         } else if keycode == LinuxKeycode::LeftArrow as u16 { | ||||
|             Some(LinuxKeycode::LeftArrow) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn is_alphabet(&self) -> bool { | ||||
|         // top row
 | ||||
|         (*self as u16 >= LinuxKeycode::Q as u16 && *self as u16 <= LinuxKeycode::P as u16) | ||||
|         || // middle row
 | ||||
|         (*self as u16 >= LinuxKeycode::A as u16 && *self as u16 <= LinuxKeycode::L as u16) | ||||
|         || // bottom row
 | ||||
|         (*self as u16 >= LinuxKeycode::Z as u16 && *self as u16 <= LinuxKeycode::M as u16) | ||||
|     } | ||||
|     
 | ||||
|     pub fn is_gamma(&self) -> bool { | ||||
|         match self { | ||||
|             LinuxKeycode::LeftBracket => true, | ||||
|             LinuxKeycode::RightBracket => true, | ||||
|             LinuxKeycode::Semicolon => true, | ||||
|             LinuxKeycode::Apostrophe => true, | ||||
|             LinuxKeycode::Grave => true, | ||||
|             LinuxKeycode::Backslash => true, | ||||
|             LinuxKeycode::Comma => true, | ||||
|             LinuxKeycode::Dot => true, | ||||
|             LinuxKeycode::Slash => true, | ||||
|             LinuxKeycode::Space => true, | ||||
|             LinuxKeycode::LeftControl => true, | ||||
|             LinuxKeycode::LeftShift => true, | ||||
|             LinuxKeycode::LeftAlt => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn is_delta(&self) -> bool { | ||||
|         match self { | ||||
|             LinuxKeycode::UpArrow => true, | ||||
|             LinuxKeycode::DownArrow => true, | ||||
|             LinuxKeycode::RightArrow => true, | ||||
|             LinuxKeycode::LeftArrow => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn to_keymap_section(&self) -> Option<KeymapSection> { | ||||
|         if (*self as u16 >= LinuxKeycode::ESC as u16 && *self as u16 <= LinuxKeycode::Tab as u16) || *self as u16 == LinuxKeycode::Enter as u16 { | ||||
|             Some(KeymapSection::Alpha) | ||||
|         } else if self.is_alphabet() { | ||||
|             Some(KeymapSection::Beta) | ||||
|         } else if self.is_gamma() { | ||||
|             Some(KeymapSection::Gamma) | ||||
|         } else if self.is_delta() { | ||||
|             Some(KeymapSection::Delta) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn to_alpha_key(&self) -> Option<KeyAlpha> { | ||||
|         const KEYCODES_TO_ALPHA: &[KeyAlpha] = &[ | ||||
|             KeyAlpha::Esc, | ||||
|             KeyAlpha::Key1, | ||||
|             KeyAlpha::Key2, | ||||
|             KeyAlpha::Key3, | ||||
|             KeyAlpha::Key4, | ||||
|             KeyAlpha::Key5, | ||||
|             KeyAlpha::Key6, | ||||
|             KeyAlpha::Key7, | ||||
|             KeyAlpha::Key8, | ||||
|             KeyAlpha::Key9, | ||||
|             KeyAlpha::Key0, | ||||
|             KeyAlpha::Minus, | ||||
|             KeyAlpha::Equal, | ||||
|             KeyAlpha::Backspace, | ||||
|             KeyAlpha::Tab, | ||||
|         ]; | ||||
|         if *self as u16 >= LinuxKeycode::ESC as u16 && *self as u16 <= LinuxKeycode::Tab as u16 { | ||||
|             Some(KEYCODES_TO_ALPHA[*self as usize - 1]) | ||||
|         } else if *self as u16 == LinuxKeycode::Enter as u16 { | ||||
|             Some(KeyAlpha::Enter) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn to_beta_key(&self) -> Option<KeyBeta> { | ||||
|         match self { | ||||
|             LinuxKeycode::Q => Some(KeyBeta::Q), | ||||
|             LinuxKeycode::W => Some(KeyBeta::W), | ||||
|             LinuxKeycode::E => Some(KeyBeta::E), | ||||
|             LinuxKeycode::R => Some(KeyBeta::R), | ||||
|             LinuxKeycode::T => Some(KeyBeta::T), | ||||
|             LinuxKeycode::Y => Some(KeyBeta::Y), | ||||
|             LinuxKeycode::U => Some(KeyBeta::U), | ||||
|             LinuxKeycode::I => Some(KeyBeta::I), | ||||
|             LinuxKeycode::O => Some(KeyBeta::O), | ||||
|             LinuxKeycode::P => Some(KeyBeta::P), | ||||
|             LinuxKeycode::A => Some(KeyBeta::A), | ||||
|             LinuxKeycode::S => Some(KeyBeta::S), | ||||
|             LinuxKeycode::D => Some(KeyBeta::D), | ||||
|             LinuxKeycode::F => Some(KeyBeta::F), | ||||
|             LinuxKeycode::G => Some(KeyBeta::G), | ||||
|             LinuxKeycode::H => Some(KeyBeta::H), | ||||
|             LinuxKeycode::J => Some(KeyBeta::J), | ||||
|             LinuxKeycode::K => Some(KeyBeta::K), | ||||
|             LinuxKeycode::L => Some(KeyBeta::L), | ||||
|             LinuxKeycode::Z => Some(KeyBeta::Z), | ||||
|             LinuxKeycode::X => Some(KeyBeta::X), | ||||
|             LinuxKeycode::C => Some(KeyBeta::C), | ||||
|             LinuxKeycode::V => Some(KeyBeta::V), | ||||
|             LinuxKeycode::B => Some(KeyBeta::B), | ||||
|             LinuxKeycode::N => Some(KeyBeta::N), | ||||
|             LinuxKeycode::M => Some(KeyBeta::M), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn to_gamma_key(&self) -> Option<KeyGamma> { | ||||
|         match self { | ||||
|             LinuxKeycode::LeftBracket => Some(KeyGamma::LeftBracket), | ||||
|             LinuxKeycode::RightBracket => Some(KeyGamma::RightBracket), | ||||
|             LinuxKeycode::Semicolon => Some(KeyGamma::Semicolon), | ||||
|             LinuxKeycode::Apostrophe => Some(KeyGamma::Apostrophe), | ||||
|             LinuxKeycode::Grave => Some(KeyGamma::Grave), | ||||
|             LinuxKeycode::Backslash => Some(KeyGamma::Backslash), | ||||
|             LinuxKeycode::Comma => Some(KeyGamma::Comma), | ||||
|             LinuxKeycode::Dot => Some(KeyGamma::Dot), | ||||
|             LinuxKeycode::Slash => Some(KeyGamma::Slash), | ||||
|             LinuxKeycode::Space => Some(KeyGamma::Space), | ||||
|             LinuxKeycode::LeftControl => Some(KeyGamma::Control), | ||||
|             LinuxKeycode::LeftShift => Some(KeyGamma::Shift), | ||||
|             LinuxKeycode::LeftAlt => Some(KeyGamma::Alt), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn to_delta_key(&self) -> Option<KeyDelta> { | ||||
|         match self { | ||||
|             LinuxKeycode::UpArrow => Some(KeyDelta::UpArrow), | ||||
|             LinuxKeycode::DownArrow => Some(KeyDelta::DownArrow), | ||||
|             LinuxKeycode::RightArrow => Some(KeyDelta::RightArrow), | ||||
|             LinuxKeycode::LeftArrow => Some(KeyDelta::LeftArrow), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // keys that do not map directly are handled outside of this
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| use core::sync::atomic::Ordering; | ||||
| use liblbos::keymap::Keymap; | ||||
| use liblbos::TaskSetup; | ||||
| use crate::arch::serial_port; | ||||
| use crate::memory::{BLOCK_SIZE, MemoryManager}; | ||||
|  | @ -380,6 +381,11 @@ pub fn handle_syscall( | |||
|                 suspend = true; | ||||
|                 0 | ||||
|             } | ||||
|             SysCall::GetCurrentKeymap => { | ||||
|                 let keymap_ptr = unsafe { &mut *(a1 as *mut Keymap) }; | ||||
|                 *keymap_ptr = tc.current_keymap; | ||||
|                 0 | ||||
|             } | ||||
|         }, | ||||
|         suspend, | ||||
|     ) | ||||
|  | @ -494,6 +500,7 @@ pub struct TrafficControl { | |||
|     pub inbuf_write: u8, | ||||
|     pub hung_system: bool, | ||||
|     pub use_fb_console: bool, | ||||
|     pub current_keymap: Keymap, | ||||
| } | ||||
| 
 | ||||
| pub struct Task { | ||||
|  | @ -528,6 +535,12 @@ impl TrafficControl { | |||
|             inbuf_write: 0, | ||||
|             hung_system: false, | ||||
|             use_fb_console: false, | ||||
|             current_keymap: Keymap { | ||||
|                 alpha: 0, | ||||
|                 beta: 0, | ||||
|                 gamma: 0, | ||||
|                 delta: 0, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue