[Teton] Terminal now owns the command str.

This commit is contained in:
Drew Galbraith 2024-08-14 07:49:06 -07:00
parent f04e720811
commit c155247f1d
3 changed files with 89 additions and 38 deletions

View File

@ -4,56 +4,33 @@ use crate::psf::Psf;
pub struct Console { pub struct Console {
framebuffer: Framebuffer, framebuffer: Framebuffer,
psf: Psf, psf: Psf,
row: u32,
col: u32,
} }
impl Console { impl Console {
pub fn new(framebuffer: Framebuffer, psf: Psf) -> Self { pub fn new(framebuffer: Framebuffer, psf: Psf) -> Self {
Self { Self { framebuffer, psf }
framebuffer,
psf,
row: 0,
col: 0,
}
} }
fn incr_cursor(&mut self) { pub fn write_char(&mut self, chr: char, row: u32, col: u32) {
self.col += 1; if row >= self.rows() {
if self.col >= self.cols() { panic!("Write at row {}, max is {}", row, self.rows())
self.col = 0;
self.row += 1;
} }
if col >= self.cols() {
if self.row >= self.rows() { panic!("Write at col {}, max is {}", col, self.cols())
panic!("Scroll unimplemented")
}
}
pub fn write_char(&mut self, chr: char) {
if chr == '\x08' {
// Backspace.
if self.col > 1 {
self.col -= 1;
self.write_char(' ');
self.col -= 1;
}
return;
} }
let glyph = self.psf.glyph(chr as u32); let glyph = self.psf.glyph(chr as u32);
self.framebuffer.draw_glyph( self.framebuffer.draw_glyph(
glyph, glyph,
self.row * (self.psf.height() + 1), row * (self.psf.height() + 1),
self.col * (self.psf.width() + 1), col * (self.psf.width() + 1),
); );
self.incr_cursor()
} }
fn cols(&self) -> u32 { pub fn cols(&self) -> u32 {
self.framebuffer.width() / (self.psf.width() + 1) self.framebuffer.width() / (self.psf.width() + 1)
} }
fn rows(&self) -> u32 { pub fn rows(&self) -> u32 {
self.framebuffer.height() / (self.psf.height() + 1) self.framebuffer.height() / (self.psf.height() + 1)
} }
} }

View File

@ -38,9 +38,7 @@ extern "C" fn main() -> z_err_t {
.expect("Failed to create framebuffer"); .expect("Failed to create framebuffer");
let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file."); let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file.");
let mut console = console::Console::new(framebuffer, psf); let console = console::Console::new(framebuffer, psf);
console.write_char('>');
let terminal = Rc::new(RefCell::new(terminal::Terminal::new(console))); let terminal = Rc::new(RefCell::new(terminal::Terminal::new(console)));
let kb_listener = KeyboardListener::new(terminal).expect("Failed to create keyboard listener"); let kb_listener = KeyboardListener::new(terminal).expect("Failed to create keyboard listener");

View File

@ -1,18 +1,94 @@
use core::str::Split;
use crate::console::Console; use crate::console::Console;
use alloc::{
format,
string::{String, ToString},
};
use voyageurs::listener::KeyboardHandler; use voyageurs::listener::KeyboardHandler;
pub struct Terminal { pub struct Terminal {
console: Console, console: Console,
curr_cmd: String,
cwd: String,
row: u32,
} }
impl KeyboardHandler for Terminal { impl KeyboardHandler for Terminal {
fn handle_char(&mut self, c: char) { fn handle_char(&mut self, c: char) {
self.console.write_char(c) let mut should_execute = false;
match c {
'\x08' => {
let mut chars = self.curr_cmd.chars();
chars.next_back(); // Pop last char.
self.curr_cmd = chars.collect();
}
'\n' => should_execute = true,
_ => self.curr_cmd.push(c),
}
self.rewrite_command();
if should_execute {
self.execute_command();
self.rewrite_command();
}
} }
} }
impl Terminal { impl Terminal {
pub fn new(console: Console) -> Self { pub fn new(console: Console) -> Self {
Self { console } let mut term = Self {
console,
curr_cmd: String::new(),
cwd: "/".to_string(),
row: 0,
};
term.rewrite_command();
term
}
fn rewrite_command(&mut self) {
self.console.write_char('>', self.row, 0);
let mut col = 1;
for c in self.curr_cmd.chars() {
self.console.write_char(c, self.row, col);
col += 1;
}
// Hacky way to properly backspace.
// FIXME: This won't work once we have line wrapping.
self.console.write_char(' ', self.row, col)
}
fn write_line(&mut self, line: &str) {
let mut col = 0;
for c in line.chars() {
self.console.write_char(c, self.row, col);
col += 1;
}
self.row += 1
}
fn execute_command(&mut self) {
self.row += 1;
let curr_cmd = self.curr_cmd.clone();
let mut tokens = curr_cmd.split(' ');
match tokens.next() {
None => {}
Some(command) => self.execute_command_parsed(command, tokens),
}
self.curr_cmd.clear()
}
fn execute_command_parsed(&mut self, cmd: &str, _args: Split<'_, char>) {
match cmd {
"help" => self.write_line("Available commands are 'pwd', 'ls', 'cd', and 'exec'"),
"pwd" => self.write_line(&self.cwd.clone()),
_ => self.write_line(&format!("Unrecognized command: {}", cmd)),
}
} }
} }