fix VGA color on x86_64

master
WangRunji 6 years ago
parent e70cac58c8
commit a3edd38046

35
kernel/Cargo.lock generated

@ -137,6 +137,14 @@ name = "fuchsia-cprng"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "getopts" name = "getopts"
version = "0.2.18" version = "0.2.18"
@ -145,6 +153,23 @@ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "hash32"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heapless"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.3.0" version = "1.3.0"
@ -266,6 +291,7 @@ dependencies = [
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
"console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)", "device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)",
"heapless 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -423,6 +449,11 @@ name = "tock-registers"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "uart_16550" name = "uart_16550"
version = "0.1.0" version = "0.1.0"
@ -549,7 +580,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0"
"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8107dafa78c80c848b71b60133954b4a58609a3a1a5f9af037ecc7f67280f369"
"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
"checksum hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12d790435639c06a7b798af9e1e331ae245b7ef915b92f70a39b4cf8c00686af"
"checksum heapless 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "56b960caff1a46f1fb3c1eb05f0575ac21c6248364ebebde11b11116e099881c"
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
"checksum linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "655d57c71827fe0891ce72231b6aa5e14033dae3f604609e6a6f807267c1678d" "checksum linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "655d57c71827fe0891ce72231b6aa5e14033dae3f604609e6a6f807267c1678d"
@ -581,6 +615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" "checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum tock-registers 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316" "checksum tock-registers 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e" "checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" "checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5"

@ -45,6 +45,7 @@ xmas-elf = "0.6"
bitflags = "1.0" bitflags = "1.0"
bit_field = "0.9" bit_field = "0.9"
volatile = "0.2" volatile = "0.2"
heapless = "0.4"
console-traits = "0.3" console-traits = "0.3"
linked_list_allocator = "0.6" linked_list_allocator = "0.6"
device_tree = { git = "https://github.com/jiegec/device_tree-rs" } device_tree = { git = "https://github.com/jiegec/device_tree-rs" }

@ -207,7 +207,7 @@ debug: $(kernel) $(bin)
build: $(bin) build: $(bin)
asm: asm:
@$(objdump) -dS $(kernel) | less @$(objdump) -d $(kernel) | less
header: header:
@$(objdump) -h $(kernel) @$(objdump) -h $(kernel)

@ -1,7 +1,9 @@
//! Frambuffer color //! Frambuffer color
use crate::util::color::ConsoleColor;
pub trait FramebufferColor { pub trait FramebufferColor {
/// pack as 32-bit integer /// pack as 16-bit integer
fn pack16(&self) -> u16; fn pack16(&self) -> u16;
/// pack as 32-bit integer /// pack as 32-bit integer
@ -12,34 +14,12 @@ pub trait FramebufferColor {
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct RgbColor(u8, u8, u8); pub struct RgbColor(u8, u8, u8);
#[repr(u8)]
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ConsoleColor {
Black = 0,
Red = 1,
Green = 2,
Yellow = 3,
Blue = 4,
Magenta = 5,
Cyan = 6,
White = 7,
BrightBlack = 60,
BrightRed = 61,
BrightGreen = 62,
BrightYellow = 63,
BrightBlue = 64,
BrightMagenta = 65,
BrightCyan = 66,
BrightWhite = 67,
}
use self::ConsoleColor::*;
impl From<ConsoleColor> for RgbColor { impl From<ConsoleColor> for RgbColor {
/// Convert `ConsoleColor` to `RgbColor`. /// Convert `ConsoleColor` to `RgbColor`.
/// use `CMD` color scheme. /// use `CMD` color scheme.
/// (ref: https://en.wikipedia.org/wiki/ANSI_escape_code) /// (ref: https://en.wikipedia.org/wiki/ANSI_escape_code)
fn from(color: ConsoleColor) -> Self { fn from(color: ConsoleColor) -> Self {
use self::ConsoleColor::*;
match color { match color {
Black => RgbColor(0, 0, 0), Black => RgbColor(0, 0, 0),
Red => RgbColor(128, 0, 0), Red => RgbColor(128, 0, 0),

@ -1,21 +1,23 @@
//! Framebuffer console display driver for ARM64 //! Framebuffer console display driver for ARM64
mod color;
mod escape_parser;
mod fonts;
use self::color::FramebufferColor;
use self::escape_parser::{CharacterAttribute, EscapeParser};
use self::fonts::{Font, Font8x16};
use super::fb::{ColorDepth::*, FramebufferInfo, FRAME_BUFFER};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::fmt; use core::fmt;
use core::marker::PhantomData; use core::marker::PhantomData;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use log::*; use log::*;
use spin::Mutex; use spin::Mutex;
use crate::util::escape_parser::{CharacterAttribute, EscapeParser};
use super::fb::{ColorDepth::*, FRAME_BUFFER, FramebufferInfo};
use self::color::FramebufferColor;
use self::fonts::{Font, Font8x16};
mod color;
mod fonts;
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct ConsoleChar { pub struct ConsoleChar {

@ -8,6 +8,7 @@ pub mod consts;
pub mod cpu; pub mod cpu;
pub mod driver; pub mod driver;
pub mod timer; pub mod timer;
pub mod syscall;
#[cfg(feature = "board_raspi3")] #[cfg(feature = "board_raspi3")]
#[path = "board/raspi3/mod.rs"] #[path = "board/raspi3/mod.rs"]

@ -0,0 +1,4 @@
pub fn translate(id: usize) -> usize {
// FIXME: translate syscall id on aarch64
id
}

@ -1,18 +1,45 @@
use core::fmt; use core::fmt;
use console_traits::*;
use lazy_static::lazy_static;
use spin::Mutex; use spin::Mutex;
use volatile::Volatile; use volatile::Volatile;
use lazy_static::lazy_static;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
use crate::logging::Color;
use crate::consts::KERNEL_OFFSET; use crate::consts::KERNEL_OFFSET;
use console_traits::*; use crate::util::color::ConsoleColor;
use crate::util::escape_parser::EscapeParser;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
struct ColorCode(u8); struct ColorCode(u8);
impl ColorCode { impl ColorCode {
const fn new(foreground: Color, background: Color) -> ColorCode { fn new(foreground: ConsoleColor, background: ConsoleColor) -> ColorCode {
ColorCode((background as u8) << 4 | (foreground as u8)) ColorCode(background.to_code() << 4 | foreground.to_code())
}
}
impl ConsoleColor {
fn to_code(&self) -> u8 {
use self::ConsoleColor::*;
match self {
Black => 0,
Blue => 1,
Green => 2,
Cyan => 3,
Red => 4,
Magenta => 5,
Yellow => 6,
White => 7,
BrightBlack => 8,
BrightBlue => 9,
BrightGreen => 10,
BrightCyan => 11,
BrightRed => 12,
BrightMagenta => 13,
BrightYellow => 14,
BrightWhite => 15,
}
} }
} }
@ -24,7 +51,7 @@ pub struct ScreenChar {
} }
impl ScreenChar { impl ScreenChar {
pub const fn new(ascii_char: u8, foreground_color: Color, background_color: Color) -> Self { pub fn new(ascii_char: u8, foreground_color: ConsoleColor, background_color: ConsoleColor) -> Self {
ScreenChar { ScreenChar {
ascii_char, ascii_char,
color_code: ColorCode::new(foreground_color, background_color) color_code: ColorCode::new(foreground_color, background_color)
@ -41,7 +68,7 @@ pub struct VgaBuffer {
impl VgaBuffer { impl VgaBuffer {
pub fn clear(&mut self) { pub fn clear(&mut self) {
let blank = ScreenChar::new(b' ', Color::LightGray, Color::Black); let blank = ScreenChar::new(b' ', ConsoleColor::White, ConsoleColor::Black);
for row in 0 .. BUFFER_HEIGHT { for row in 0 .. BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH { for col in 0..BUFFER_WIDTH {
self.chars[row][col].write(blank); self.chars[row][col].write(blank);
@ -76,9 +103,10 @@ lazy_static! {
pub struct VgaWriter { pub struct VgaWriter {
pos: Position, pos: Position,
color: Color, color_code: ColorCode,
ctrl_char_mode: ControlCharMode, ctrl_char_mode: ControlCharMode,
esc_char_mode: EscapeCharMode, esc_char_mode: EscapeCharMode,
escape_parser: EscapeParser,
buffer: &'static mut VgaBuffer, buffer: &'static mut VgaBuffer,
} }
@ -105,6 +133,7 @@ impl BaseConsole for VgaWriter {
fn set_pos(&mut self, pos: Position) -> Result<(), Self::Error> { fn set_pos(&mut self, pos: Position) -> Result<(), Self::Error> {
self.pos = pos; self.pos = pos;
self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize);
Ok(()) Ok(())
} }
@ -135,24 +164,35 @@ impl BaseConsole for VgaWriter {
self.buffer.write(row - 1, col, screen_char); self.buffer.write(row - 1, col, screen_char);
} }
} }
let blank = ScreenChar::new(b' ', self.color, Color::Black); let blank = ScreenChar::new(b' ', ConsoleColor::White, ConsoleColor::Black);
for col in 0..BUFFER_WIDTH { for col in 0..BUFFER_WIDTH {
self.buffer.write(BUFFER_HEIGHT - 1, col, blank); self.buffer.write(BUFFER_HEIGHT - 1, col, blank);
} }
self.buffer.set_cursor_at(BUFFER_HEIGHT - 1, 0);
Ok(()) Ok(())
} }
} }
impl AsciiConsole for VgaWriter { impl AsciiConsole for VgaWriter {
fn write_char_at(&mut self, ch: u8, pos: Position) -> Result<(), Self::Error> { fn write_char_at(&mut self, ch: u8, pos: Position) -> Result<(), Self::Error> {
self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, ScreenChar::new(ch, self.color, Color::Black)); let screen_char = ScreenChar {
self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); ascii_char: ch,
color_code: self.color_code,
};
self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, screen_char);
Ok(()) Ok(())
} }
fn handle_escape(&mut self, escaped_char: u8) -> bool { fn handle_escape(&mut self, escaped_char: u8) -> bool {
true if escaped_char == b'[' {
self.escape_parser.start_parse();
}
self.escape_parser.parse(escaped_char);
let end = escaped_char == b'm';
if end {
let attr = self.escape_parser.char_attribute();
self.color_code = ColorCode::new(attr.foreground, attr.background);
}
end
} }
} }
@ -161,16 +201,13 @@ impl VgaWriter {
buffer.clear(); buffer.clear();
VgaWriter { VgaWriter {
pos: Position::origin(), pos: Position::origin(),
color: Color::LightGray, color_code: ColorCode::new(ConsoleColor::White, ConsoleColor::Black),
ctrl_char_mode: ControlCharMode::Interpret, ctrl_char_mode: ControlCharMode::Interpret,
esc_char_mode: EscapeCharMode::Waiting, esc_char_mode: EscapeCharMode::Waiting,
escape_parser: EscapeParser::new(),
buffer, buffer,
} }
} }
pub fn set_color(&mut self, color: Color) {
self.color = color;
}
} }
impl fmt::Write for VgaWriter { impl fmt::Write for VgaWriter {

@ -1,10 +1,13 @@
use core::fmt; use core::fmt;
use lazy_static::lazy_static;
use log::{self, Level, LevelFilter, Log, Metadata, Record}; use log::{self, Level, LevelFilter, Log, Metadata, Record};
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use lazy_static::lazy_static; use crate::util::color::ConsoleColor;
lazy_static! { lazy_static! {
static ref log_mutex: Mutex<()> = Mutex::new(()); static ref LOG_LOCK: Mutex<()> = Mutex::new(());
} }
pub fn init() { pub fn init() {
@ -37,20 +40,20 @@ macro_rules! println {
/// Add escape sequence to print with color in Linux console /// Add escape sequence to print with color in Linux console
macro_rules! with_color { macro_rules! with_color {
($args: ident, $color: ident) => {{ ($args: ident, $color: ident) => {{
let (show, code) = color_to_console_code($color); let code = $color.to_console_code();
format_args!("\u{1B}[{};{}m{}\u{1B}[0m", show.clone(), code + 30, $args) format_args!("\u{1B}[{}m{}\u{1B}[0m", code as u8, $args)
}}; }};
} }
fn print_in_color(args: fmt::Arguments, color: Color) { fn print_in_color(args: fmt::Arguments, color: ConsoleColor) {
use crate::arch::io; use crate::arch::io;
let _guard = log_mutex.lock(); let _guard = LOG_LOCK.lock();
io::putfmt(with_color!(args, color)); io::putfmt(with_color!(args, color));
} }
pub fn print(args: fmt::Arguments) { pub fn print(args: fmt::Arguments) {
use crate::arch::io; use crate::arch::io;
let _guard = log_mutex.lock(); let _guard = LOG_LOCK.lock();
io::putfmt(args); io::putfmt(args);
} }
@ -66,63 +69,20 @@ impl Log for SimpleLogger {
if self.enabled(record.metadata()) && !DISABLED_TARGET.contains(&record.target()) { if self.enabled(record.metadata()) && !DISABLED_TARGET.contains(&record.target()) {
// let target = record.target(); // let target = record.target();
// let begin = target.as_bytes().iter().rposition(|&c| c == b':').map(|i| i + 1).unwrap_or(0); // let begin = target.as_bytes().iter().rposition(|&c| c == b':').map(|i| i + 1).unwrap_or(0);
print_in_color(format_args!("[{:>5}] {}\n", record.level(), record.args()), Color::from(record.level())); print_in_color(format_args!("[{:>5}] {}\n", record.level(), record.args()), ConsoleColor::from(record.level()));
} }
} }
fn flush(&self) {} fn flush(&self) {}
} }
impl From<Level> for Color { impl From<Level> for ConsoleColor {
fn from(level: Level) -> Self { fn from(level: Level) -> Self {
match level { match level {
Level::Error => Color::Red, Level::Error => ConsoleColor::Red,
Level::Warn => Color::Yellow, Level::Warn => ConsoleColor::Yellow,
Level::Info => Color::Blue, Level::Info => ConsoleColor::Blue,
Level::Debug => Color::Green, Level::Debug => ConsoleColor::Green,
Level::Trace => Color::DarkGray, Level::Trace => ConsoleColor::BrightBlack,
} }
} }
} }
fn color_to_console_code(color: Color) -> (u8, u8) {
match color {
Color::Black => (0, 0),
Color::Blue => (0, 4),
Color::Green => (0, 2),
Color::Cyan => (0, 6),
Color::Red => (0, 1),
Color::Magenta => (0, 5),
Color::Brown => (0, 3),
Color::LightGray => (1, 7),
Color::DarkGray => (0, 7),
Color::LightBlue => (1, 4),
Color::LightGreen => (1, 2),
Color::LightCyan => (1, 6),
Color::LightRed => (1, 1),
Color::Pink => (1, 5),
Color::Yellow => (1, 3),
Color::White => (1, 0),
}
}
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u8)]
pub enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
Pink = 13,
Yellow = 14,
White = 15,
}

@ -301,6 +301,7 @@ pub enum SysError {
#[allow(non_snake_case)] #[allow(non_snake_case)]
impl fmt::Display for SysError { impl fmt::Display for SysError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SysError::*;
write!(f, "{}", write!(f, "{}",
match self { match self {
EPERM => "Operation not permitted", EPERM => "Operation not permitted",

@ -0,0 +1,65 @@
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ConsoleColor {
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
BrightBlack,
BrightRed,
BrightGreen,
BrightYellow,
BrightBlue,
BrightMagenta,
BrightCyan,
BrightWhite,
}
impl ConsoleColor {
pub fn to_console_code(&self) -> u8 {
use self::ConsoleColor::*;
match self {
Black => 30,
Red => 31,
Green => 32,
Yellow => 33,
Blue => 34,
Magenta => 35,
Cyan => 36,
White => 37,
BrightBlack => 90,
BrightRed => 91,
BrightGreen => 92,
BrightYellow => 93,
BrightBlue => 94,
BrightMagenta => 95,
BrightCyan => 96,
BrightWhite => 97,
}
}
pub fn from_console_code(code: u8) -> Option<ConsoleColor> {
use self::ConsoleColor::*;
match code {
30 => Some(Black),
31 => Some(Red),
32 => Some(Green),
33 => Some(Yellow),
34 => Some(Blue),
35 => Some(Magenta),
36 => Some(Cyan),
37 => Some(White),
90 => Some(BrightBlack),
91 => Some(BrightRed),
92 => Some(BrightGreen),
93 => Some(BrightYellow),
94 => Some(BrightBlue),
95 => Some(BrightMagenta),
96 => Some(BrightCyan),
97 => Some(BrightWhite),
_ => None,
}
}
}

@ -1,16 +1,17 @@
//! ANSI escape sequences parser //! ANSI escape sequences parser
//! (ref: https://en.wikipedia.org/wiki/ANSI_escape_code) //! (ref: https://en.wikipedia.org/wiki/ANSI_escape_code)
use super::color::{ConsoleColor, ConsoleColor::*, FramebufferColor}; use heapless::Vec;
use alloc::vec::Vec; use heapless::consts::U8;
use super::color::ConsoleColor;
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct CharacterAttribute<C: FramebufferColor = ConsoleColor> { pub struct CharacterAttribute {
/// foreground color /// foreground color
pub foreground: C, pub foreground: ConsoleColor,
/// background color /// background color
pub background: C, pub background: ConsoleColor,
/// show underline /// show underline
pub underline: bool, pub underline: bool,
/// swap foreground and background colors /// swap foreground and background colors
@ -22,8 +23,8 @@ pub struct CharacterAttribute<C: FramebufferColor = ConsoleColor> {
impl Default for CharacterAttribute { impl Default for CharacterAttribute {
fn default() -> Self { fn default() -> Self {
CharacterAttribute { CharacterAttribute {
foreground: White, foreground: ConsoleColor::White,
background: Black, background: ConsoleColor::Black,
underline: false, underline: false,
reverse: false, reverse: false,
strikethrough: false, strikethrough: false,
@ -50,7 +51,7 @@ pub struct EscapeParser {
status: ParseStatus, status: ParseStatus,
char_attr: CharacterAttribute, char_attr: CharacterAttribute,
current_param: Option<u8>, current_param: Option<u8>,
params: Vec<u8>, params: Vec<u8, U8>,
} }
impl EscapeParser { impl EscapeParser {
@ -69,14 +70,13 @@ impl EscapeParser {
/// See an `ECS` character, start parsing escape sequence. /// See an `ECS` character, start parsing escape sequence.
pub fn start_parse(&mut self) { pub fn start_parse(&mut self) {
assert!(self.status == ParseStatus::Text); assert_eq!(self.status, ParseStatus::Text);
self.status = ParseStatus::BeginEscapeSequence; self.status = ParseStatus::BeginEscapeSequence;
self.current_param = None; self.current_param = None;
} }
//// Parse SGR (Select Graphic Rendition) parameters. //// Parse SGR (Select Graphic Rendition) parameters.
fn parse_sgr_params(&mut self) { fn parse_sgr_params(&mut self) {
use core::mem::transmute;
for param in &self.params { for param in &self.params {
match param { match param {
0 => self.char_attr = CharacterAttribute::default(), 0 => self.char_attr = CharacterAttribute::default(),
@ -86,8 +86,8 @@ impl EscapeParser {
24 => self.char_attr.underline = false, 24 => self.char_attr.underline = false,
27 => self.char_attr.reverse = false, 27 => self.char_attr.reverse = false,
29 => self.char_attr.strikethrough = false, 29 => self.char_attr.strikethrough = false,
30...37 | 90...97 => self.char_attr.foreground = unsafe { transmute(param - 30) }, 30...37 | 90...97 => self.char_attr.foreground = ConsoleColor::from_console_code(*param).unwrap(),
40...47 | 100...107 => self.char_attr.background = unsafe { transmute(param - 40) }, 40...47 | 100...107 => self.char_attr.background = ConsoleColor::from_console_code(*param - 10).unwrap(),
_ => { /* unimplemented!() */ } _ => { /* unimplemented!() */ }
} }
} }
@ -95,7 +95,7 @@ impl EscapeParser {
/// See a character during parsing. /// See a character during parsing.
pub fn parse(&mut self, byte: u8) -> bool { pub fn parse(&mut self, byte: u8) -> bool {
assert!(self.status != ParseStatus::Text); assert_ne!(self.status, ParseStatus::Text);
match self.status { match self.status {
ParseStatus::BeginEscapeSequence => match byte { ParseStatus::BeginEscapeSequence => match byte {
b'[' => { b'[' => {
@ -117,7 +117,7 @@ impl EscapeParser {
} }
b';' => { b';' => {
if let Some(param) = self.current_param { if let Some(param) = self.current_param {
self.params.push(param); self.params.push(param).unwrap();
} }
self.current_param = Some(0); self.current_param = Some(0);
return true; return true;
@ -125,7 +125,7 @@ impl EscapeParser {
// @AZ[\]^_`az{|}~ // @AZ[\]^_`az{|}~
0x40...0x7E => { 0x40...0x7E => {
if let Some(param) = self.current_param { if let Some(param) = self.current_param {
self.params.push(param); self.params.push(param).unwrap();
} }
match byte { match byte {
b'm' => self.parse_sgr_params(), b'm' => self.parse_sgr_params(),

@ -1,3 +1,6 @@
pub mod color;
pub mod escape_parser;
/// Convert C string to Rust string /// Convert C string to Rust string
pub unsafe fn from_cstr(s: *const u8) -> &'static str { pub unsafe fn from_cstr(s: *const u8) -> &'static str {
use core::{str, slice}; use core::{str, slice};
Loading…
Cancel
Save