1
0
Fork 0
forked from AbleOS/ableos
ableos-idl/ableos/src/vterm.rs

260 lines
7.7 KiB
Rust
Raw Normal View History

use crate::{hardware::MOUSE, vga_e::VGAE};
use logos::{Lexer, Logos};
2022-07-31 01:54:01 -05:00
use vga::{colors::Color16, writers::GraphicsWriter};
const TERM_MINUS_ONE_LINE: usize = 4720;
2022-08-02 01:52:03 -05:00
const CURSOR_COLOR: Color16 = Color16::Cyan;
2022-07-31 01:54:01 -05:00
#[derive(Debug)]
pub struct Term {
dirty: bool,
term: [(char, Color16); 80 * 60],
2022-07-31 05:22:39 -05:00
x: u8,
2022-07-31 01:54:01 -05:00
}
impl Term {
pub fn new() -> Self {
2022-07-31 05:22:39 -05:00
let mode = VGAE.lock();
mode.set_mode();
drop(mode);
2022-07-31 01:54:01 -05:00
Self {
dirty: false,
x: 0,
term: [('\0', Color16::LightGrey); 80 * 60],
2022-07-31 01:54:01 -05:00
}
}
pub fn is_dirty(&self) -> bool {
self.dirty
}
pub fn set_dirty(&mut self, dirty: bool) {
self.dirty = dirty
}
pub fn print(&mut self, data: &str) {
2022-07-31 01:54:01 -05:00
for c in data.chars() {
2022-07-31 05:22:39 -05:00
if self.x == 79 {
2022-07-31 01:54:01 -05:00
self.move_up();
2022-07-31 05:22:39 -05:00
return;
}
match c {
'\u{08}' => {
if self.x == 0 {
// trace!("IMPOSSIBLE BACKSPACE");
return;
2022-07-31 05:22:39 -05:00
}
2022-07-31 06:21:50 -05:00
trace!("BACKSPACE");
self.x -= 1;
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = ('\0', Color16::LightGrey);
2022-07-31 05:22:39 -05:00
}
'\n' => {
self.move_up();
self.x = 0;
}
c => {
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (c, Color16::White);
2022-07-31 05:22:39 -05:00
self.x += 1;
}
2022-07-31 01:54:01 -05:00
}
}
}
// TODO:DEADLOCK: Fix this up
pub fn cprint(&mut self, data: &str) {
let lex = Token::lexer(data);
trace!("{:?}", lex);
let mut color = Color16::Red;
for toke in lex {
match toke {
Token::Error =>
// unsafe { asm!("int 54") },
{}
Token::TBlack => color = Color16::Black,
Token::TBlue => {
color = Color16::Blue;
trace!("");
}
Token::TGreen => color = Color16::Green,
Token::TCyan => color = Color16::Cyan,
Token::TRed => color = Color16::Red,
Token::TMagenta => color = Color16::Magenta,
Token::TBrown => color = Color16::Brown,
Token::TLightGrey => color = Color16::LightGrey,
Token::TDarkGrey => color = Color16::DarkGrey,
Token::TLightBlue => color = Color16::LightBlue,
Token::TLightGreen => color = Color16::LightGreen,
Token::TLightCyan => color = Color16::LightCyan,
Token::TLightRed => color = Color16::LightRed,
Token::TPink => color = Color16::Pink,
Token::TYellow => color = Color16::Yellow,
Token::TWhite => color = Color16::White,
Token::Text(st) => {
for c in st.chars() {
if self.x == 79 {
self.move_up();
return;
}
match c {
'\u{08}' => {
if self.x == 0 {
// trace!("IMPOSSIBLE BACKSPACE");
return;
}
trace!("BACKSPACE");
self.x -= 1;
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] =
('\0', Color16::LightGrey);
}
'\n' => {
self.move_up();
self.x = 0;
}
c => {
self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = (c, color);
self.x += 1;
}
}
}
}
}
}
}
2022-07-31 01:54:01 -05:00
pub fn move_up(&mut self) {
self.term.rotate_left(80);
for x in 0..80 {
self.term[TERM_MINUS_ONE_LINE + x] = ('\0', Color16::LightGrey);
2022-07-31 01:54:01 -05:00
}
2022-07-31 05:22:39 -05:00
self.x = 0;
2022-07-31 01:54:01 -05:00
}
2022-07-31 05:22:39 -05:00
// pub fn initialize(&self) {
// let mode = VGAE.lock();
// mode.set_mode();
// drop(mode);
// }
2022-07-31 01:54:01 -05:00
pub fn draw_term(&mut self) {
if self.is_dirty() {
trace!("Redrawing");
2022-08-02 01:52:03 -05:00
use Color16::*;
2022-07-31 01:54:01 -05:00
let mode = VGAE.lock();
2022-08-02 01:52:03 -05:00
mode.clear_screen(DarkGrey);
2022-07-31 01:54:01 -05:00
let mouse_coord = x86_64::instructions::interrupts::without_interrupts(|| {
let cursor = MOUSE.lock();
2022-07-31 01:54:01 -05:00
(cursor.get_x() as usize, cursor.get_y() as usize)
});
2022-07-31 01:54:01 -05:00
mode.draw_line(
(mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0),
(mouse_coord.0 as isize + 10, mouse_coord.1 as isize + 10),
CURSOR_COLOR,
);
mode.draw_line(
(mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0),
(mouse_coord.0 as isize + 5, mouse_coord.1 as isize + 0),
CURSOR_COLOR,
);
mode.draw_line(
(mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 0),
(mouse_coord.0 as isize + 0, mouse_coord.1 as isize + 5),
CURSOR_COLOR,
);
2022-07-31 01:54:01 -05:00
let mut x = 0;
let mut y = 0;
for c in self.term {
mode.draw_character(x * 8, y * 8, c.0, c.1);
2022-07-31 01:54:01 -05:00
if x == 79 {
y += 1;
x = 0;
} else {
x += 1
}
}
2022-08-02 01:52:03 -05:00
2022-07-31 03:03:59 -05:00
self.set_dirty(false);
2022-07-31 01:54:01 -05:00
trace!("Finished drawing");
}
}
}
#[derive(Logos, Debug, Clone, PartialEq)]
pub enum Token {
#[regex(r"[\t\n\f]+", logos::skip)]
#[error]
Error,
#[token("$BLACK$")]
TBlack,
#[token("$BLUE$")]
TBlue,
#[token("$GREEN$")]
TGreen,
#[token("$CYAN$")]
TCyan,
#[token("$RED$")]
TRed,
#[token("$MAGENTA$")]
TMagenta,
#[token("$BROWN$")]
TBrown,
#[token("$LIGHTGREY$")]
TLightGrey,
#[token("$DARKGREY$")]
TDarkGrey,
#[token("$LIGHTBLUE$")]
TLightBlue,
#[token("$LIGHTGREEN$")]
TLightGreen,
#[token("$LIGHTCYAN$")]
TLightCyan,
#[token("$LIGHTRED$")]
TLightRed,
#[token("$PINK$")]
TPink,
#[token("$YELLOW$")]
TYellow,
#[token("$WHITE$")]
TWhite,
#[regex("/[\x00-\x7F]/", text_lex)]
Text(String),
}
fn text_lex(lex: &mut Lexer<Token>) -> String {
lex.slice().into()
}
impl Into<Color16> for Token {
fn into(self) -> Color16 {
match self {
Token::Error => todo!(),
Token::TBlack => Color16::Black,
Token::TBlue => Color16::Blue,
Token::TGreen => Color16::Green,
Token::TCyan => Color16::Cyan,
Token::TRed => Color16::Red,
Token::TMagenta => Color16::Magenta,
Token::TBrown => Color16::Brown,
Token::TLightGrey => Color16::LightGrey,
Token::TDarkGrey => Color16::DarkGrey,
Token::TLightBlue => Color16::LightBlue,
Token::TLightGreen => Color16::LightGreen,
Token::TLightCyan => Color16::LightCyan,
Token::TLightRed => Color16::LightRed,
Token::TPink => Color16::Pink,
Token::TYellow => Color16::Yellow,
Token::TWhite => Color16::White,
Token::Text(_) => todo!(),
}
}
}