Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ANSI Style type #76

Merged
merged 3 commits into from
Jul 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 80 additions & 21 deletions src/kernel/console.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,88 @@
use crate::{kernel, print};
use alloc::string::String;
use core::fmt;
use lazy_static::lazy_static;
use spin::Mutex;
use x86_64::instructions::interrupts;

pub fn color(name: &str) -> &str {
pub struct Style {
foreground: Option<usize>,
background: Option<usize>,
}

impl Style {
pub fn reset() -> Self {
Self { foreground: None, background: None }
}

pub fn foreground(name: &str) -> Self {
Self { foreground: color_to_fg(name), background: None }
}

pub fn with_foreground(self, name: &str) -> Self {
Self { foreground: color_to_fg(name), background: self.background }
}

pub fn background(name: &str) -> Self {
Self { foreground: None, background: color_to_bg(name) }
}

pub fn with_background(self, name: &str) -> Self {
Self { foreground: self.foreground, background: color_to_bg(name) }
}

pub fn color(name: &str) -> Self {
Self::foreground(name)
}

pub fn with_color(self, name: &str) -> Self {
self.with_foreground(name)
}
}

impl fmt::Display for Style {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(fg) = self.foreground {
if let Some(bg) = self.background {
write!(f, "\x1b[{};{}m", fg, bg)
} else {
write!(f, "\x1b[{}m", fg)
}
} else if let Some(bg) = self.background {
write!(f, "\x1b[{}m", bg)
} else {
write!(f, "\x1b[0m")
}
}
}

fn color_to_fg(name: &str) -> Option<usize> {
match name {
"Black" => "\x1b[30m",
"Red" => "\x1b[31m",
"Green" => "\x1b[32m",
"Brown" => "\x1b[33m",
"Blue" => "\x1b[34m",
"Magenta" => "\x1b[35m",
"Cyan" => "\x1b[36m",
"LightGray" => "\x1b[37m",
"DarkGray" => "\x1b[90m",
"LightRed" => "\x1b[91m",
"LightGreen" => "\x1b[92m",
"Yellow" => "\x1b[93m",
"LightBlue" => "\x1b[94m",
"Pink" => "\x1b[95m",
"LightCyan" => "\x1b[96m",
"White" => "\x1b[97m",
"Reset" => "\x1b[0m",
_ => "",
"Black" => Some(30),
"Red" => Some(31),
"Green" => Some(32),
"Brown" => Some(33),
"Blue" => Some(34),
"Magenta" => Some(35),
"Cyan" => Some(36),
"LightGray" => Some(37),
"DarkGray" => Some(90),
"LightRed" => Some(91),
"LightGreen" => Some(92),
"Yellow" => Some(93),
"LightBlue" => Some(94),
"Pink" => Some(95),
"LightCyan" => Some(96),
"White" => Some(97),
_ => None,
}
}

fn color_to_bg(name: &str) -> Option<usize> {
if let Some(fg) = color_to_fg(name) {
Some(fg + 10)
} else {
None
}
}

Expand Down Expand Up @@ -99,8 +158,8 @@ macro_rules! print {
macro_rules! log {
($($arg:tt)*) => ({
let uptime = $crate::kernel::clock::uptime();
let csi_color = $crate::kernel::console::color("LightGreen");
let csi_reset = $crate::kernel::console::color("Reset");
let csi_color = $crate::kernel::console::Style::color("LightGreen");
let csi_reset = $crate::kernel::console::Style::reset();
if cfg!(feature="vga") {
$crate::kernel::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
$crate::kernel::vga::print_fmt(format_args!($($arg)*));
Expand Down
10 changes: 3 additions & 7 deletions src/kernel/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,16 @@ impl Serial {
Self { port }
}

fn write_string(&mut self, s: &str) {
for byte in s.bytes() {
self.write_byte(byte)
}
}

pub fn write_byte(&mut self, byte: u8) {
self.port.send(byte);
}
}

impl fmt::Write for Serial {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
for byte in s.bytes() {
self.write_byte(byte)
}
Ok(())
}
}
Expand Down
13 changes: 5 additions & 8 deletions src/kernel/vga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const BG: Color = Color::Black;
const UNPRINTABLE: u8 = 0xFE; // Unprintable characters will be replaced by a square

lazy_static! {
pub static ref PARSER: Mutex<vte::Parser> = Mutex::new(vte::Parser::new());
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer {
cursor: [0; 2],
writer: [0; 2],
Expand Down Expand Up @@ -198,13 +199,6 @@ impl Writer {
}
}

fn write_string(&mut self, s: &str) {
let mut state_machine = vte::Parser::new();
for byte in s.bytes() {
state_machine.advance(self, byte);
}
}

fn new_line(&mut self) {
if self.writer[1] < BUFFER_HEIGHT - 1 {
self.writer[1] += 1;
Expand Down Expand Up @@ -309,7 +303,10 @@ impl vte::Perform for Writer {

impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
let mut state_machine = PARSER.lock();
for byte in s.bytes() {
state_machine.advance(self, byte);
}
let (x, y) = self.writer_position();
self.set_cursor_position(x, y);
Ok(())
Expand Down
5 changes: 3 additions & 2 deletions src/user/halt.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{kernel, print, user};
use crate::kernel::console::Style;

pub fn main(_args: &[&str]) -> user::shell::ExitCode {
let csi_color = kernel::console::color("Yellow");
let csi_reset = kernel::console::color("Reset");
let csi_color = Style::color("Yellow");
let csi_reset = Style::reset();
print!("{}MOROS has reached its fate, the system is now halted.{}\n", csi_color, csi_reset);
kernel::time::sleep(3.0);
kernel::acpi::poweroff();
Expand Down
11 changes: 6 additions & 5 deletions src/user/help.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{kernel, print, user};
use crate::{print, user};
use crate::kernel::console::Style;

pub fn main(_args: &[&str]) -> user::shell::ExitCode {
let csi_color = kernel::console::color("Yellow");
let csi_reset = kernel::console::color("Reset");
let csi_color = Style::color("Yellow");
let csi_reset = Style::reset();
print!("{}Commands:{}\n", csi_color, csi_reset);
print!("\n");

Expand All @@ -20,8 +21,8 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
("w", "rite <file>", "Write file or directory\n"),
];
for (alias, command, usage) in &cmds {
let csi_col1 = kernel::console::color("LightGreen");
let csi_col2 = kernel::console::color("LightCyan");
let csi_col1 = Style::color("LightGreen");
let csi_col2 = Style::color("LightCyan");
print!(" {}{}{}{:20}{}{}", csi_col1, alias, csi_col2, command, csi_reset, usage);
}
print!("\n");
Expand Down
5 changes: 3 additions & 2 deletions src/user/install.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{kernel, print, user};
use crate::kernel::console::Style;

pub fn main(_args: &[&str]) -> user::shell::ExitCode {
let csi_color = kernel::console::color("Yellow");
let csi_reset = kernel::console::color("Reset");
let csi_color = Style::color("Yellow");
let csi_reset = Style::reset();
print!("{}Welcome to MOROS v{} installation program!{}\n", csi_color, env!("CARGO_PKG_VERSION"), csi_reset);
print!("\n");

Expand Down
5 changes: 3 additions & 2 deletions src/user/shell.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{print, user, kernel};
use crate::kernel::console::Style;
use alloc::format;
use alloc::vec;
use alloc::vec::Vec;
Expand Down Expand Up @@ -407,8 +408,8 @@ impl Shell {

fn print_prompt(&self) {
let color = if self.errored { "Red" } else { "Magenta" };
let csi_color = kernel::console::color(color);
let csi_reset = kernel::console::color("Reset");
let csi_color = Style::color(color);
let csi_reset = Style::reset();
print!("{}{}{}", csi_color, self.prompt, csi_reset);
}

Expand Down