121 lines
3.3 KiB
Rust
121 lines
3.3 KiB
Rust
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 as u64 <= 42 * 32 && 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()
|
|
}
|
|
}
|