Better virtual file system, keyboard through MMIO&VirtIO
This commit is contained in:
120
src/virtual_console.rs
Normal file
120
src/virtual_console.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
use alloc::boxed::Box;
|
||||
use io::SeekFrom;
|
||||
|
||||
use crate::{
|
||||
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
||||
vga::{self, Vga},
|
||||
virtual_fs::{self, FILE_SYSTEM, VirtualFileSystem},
|
||||
};
|
||||
|
||||
const TAB_SIZE: u64 = 4;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Cursor {
|
||||
x: u64,
|
||||
y: u64,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
pub fn new() -> Self {
|
||||
Self { x: 0, y: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VirtualConsole {
|
||||
cursor: Cursor,
|
||||
framebuffer: Box<dyn virtual_fs::VirtualNode>,
|
||||
}
|
||||
|
||||
impl VirtualConsole {
|
||||
pub fn new() -> Self {
|
||||
VirtualConsole {
|
||||
cursor: Cursor::new(),
|
||||
framebuffer: unsafe { FILE_SYSTEM.open("/dev/fb0".as_ref()).unwrap() },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_str(&mut self, s: &str) {
|
||||
s.chars().for_each(|c| self.write_char(c));
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, c: char) {
|
||||
let mut last_cursor = self.cursor;
|
||||
match c {
|
||||
'\n' => {
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y += 1;
|
||||
}
|
||||
'\r' => {
|
||||
self.cursor.x = 0;
|
||||
}
|
||||
'\x08' if self.cursor.x > 0 => {
|
||||
// Backspace
|
||||
self.cursor.x -= 1;
|
||||
for y in 0..FONT_HEIGHT as u16 {
|
||||
for x in 0..FONT_WIDTH as u16 {
|
||||
unsafe {
|
||||
self.write_pixel_unsafe(
|
||||
(self.cursor.x * FONT_WIDTH as u64) as u16 + x,
|
||||
(self.cursor.y * FONT_HEIGHT as u64) as u16 + y,
|
||||
Color::BLACK,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'\t' => {
|
||||
self.cursor.x = (self.cursor.x / TAB_SIZE + 1) * TAB_SIZE;
|
||||
}
|
||||
_ if c <= 127 as char && c >= 32 as char => {
|
||||
unsafe {
|
||||
self.draw_char_bg(
|
||||
(self.cursor.x * FONT_WIDTH as u64) as u16,
|
||||
(self.cursor.y * FONT_HEIGHT as u64) as u16,
|
||||
c,
|
||||
Color::WHITE,
|
||||
Color::BLACK,
|
||||
)
|
||||
};
|
||||
self.cursor.x += 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if self.cursor.x as usize * FONT_WIDTH >= vga::WIDTH {
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y += 1;
|
||||
}
|
||||
if self.cursor.y as usize * FONT_HEIGHT >= vga::HEIGHT {
|
||||
self.line_up();
|
||||
if last_cursor.y > 0 {
|
||||
last_cursor.y -= 1;
|
||||
}
|
||||
}
|
||||
if last_cursor != self.cursor {
|
||||
self.move_cursor_line(last_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
fn line_up(&mut self) {}
|
||||
fn move_cursor_line(&mut self, _last: Cursor) {}
|
||||
}
|
||||
|
||||
impl Draw for VirtualConsole {
|
||||
unsafe fn write_pixel_unsafe(&mut self, x: u16, y: u16, color: crate::draw::Color) {
|
||||
self.framebuffer
|
||||
.seek(SeekFrom::Start(
|
||||
(y as u64 * self.get_width() as u64 + x as u64) * size_of::<Color>() as u64,
|
||||
))
|
||||
.unwrap();
|
||||
self.framebuffer.write(&color.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn get_width(&self) -> usize {
|
||||
Vga.get_width()
|
||||
}
|
||||
|
||||
fn get_height(&self) -> usize {
|
||||
Vga.get_height()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user