diff --git a/src/low_level/vga_buffer.rs b/src/low_level/vga_buffer.rs index 8800ae2..601567c 100644 --- a/src/low_level/vga_buffer.rs +++ b/src/low_level/vga_buffer.rs @@ -1,4 +1,4 @@ -use core::fmt::{self, Write}; +use core::fmt; use lazy_static::lazy_static; use spin::Mutex; use x86_64::instructions::interrupts; @@ -33,38 +33,16 @@ lazy_static! { pub static ref WRITER: Mutex = Mutex::new(Writer::new(0, Color::Yellow, Color::Black, VGA_BUFFER,)); } - -#[doc(hidden)] -pub fn print(args: fmt::Arguments) { - interrupts::without_interrupts(|| { - WRITER.lock().write_fmt(args).unwrap(); - }); -} - -pub fn set_color(foreground: Color, background: Color) { - interrupts::without_interrupts(|| { - WRITER.lock().set_color(foreground, background); - }); -} - -pub fn clear_screen(color: Color) { - interrupts::without_interrupts(|| { - WRITER.lock().clear_screen(color); - }); -} - -pub fn backspace() { - interrupts::without_interrupts(|| { - WRITER.lock().backspace(); - }); -} -pub fn cursor_back() { - interrupts::without_interrupts(|| { - WRITER.lock().cursor_back(); - }); +pub enum CommandToWriter<'a> { + Print(fmt::Arguments<'a>), + SetColor(Color, Color), + ClearScreen(Color), + Backspace, + CursorBack, + CursorFront, } -pub fn cursor_front() { +pub fn send_command_to_writer(command: CommandToWriter) { interrupts::without_interrupts(|| { - WRITER.lock().cursor_front(); + WRITER.lock().handle_command(command); }); } diff --git a/src/low_level/vga_buffer/writer.rs b/src/low_level/vga_buffer/writer.rs index 5c3e8c2..19fecec 100644 --- a/src/low_level/vga_buffer/writer.rs +++ b/src/low_level/vga_buffer/writer.rs @@ -1,8 +1,8 @@ use super::{ buffer::{Buffer, Char, ColorCode, BUFFER_HEIGHT, BUFFER_WIDTH}, - Color, + Color, CommandToWriter, }; -use core::fmt; +use core::fmt::{self, Write}; const ACTUAL_BUFFER_WIDTH: usize = 50; //Added because input stopped working after user tried to enter the 51 character. //Probably qemu issue, maybe there is a way, but this is the temporary fix @@ -25,7 +25,19 @@ impl Writer { buffer: unsafe { &mut *(buffer as *mut Buffer) }, } } - pub fn move_cursor(&mut self, column_position: usize) { + pub fn handle_command(&mut self, command: CommandToWriter) { + match command { + CommandToWriter::Backspace => self.backspace(), + CommandToWriter::ClearScreen(color) => self.clear_screen(color), + CommandToWriter::CursorBack => self.cursor_back(), + CommandToWriter::CursorFront => self.cursor_front(), + CommandToWriter::Print(args) => self.write_fmt(args).unwrap(), + CommandToWriter::SetColor(foreground, background) => { + self.set_color(foreground, background) + } + } + } + fn move_cursor(&mut self, column_position: usize) { self.buffer.chars[BUFFER_HEIGHT - 1][self.column_position + 1].invert_colors(); if column_position == 0 { self.next_line(); @@ -34,7 +46,7 @@ impl Writer { } self.buffer.chars[BUFFER_HEIGHT - 1][self.column_position + 1].invert_colors(); } - pub fn write_byte(&mut self, byte: u8) { + fn write_byte(&mut self, byte: u8) { if byte == b'\n' || self.column_position >= ACTUAL_BUFFER_WIDTH { self.move_cursor(0); return; @@ -56,7 +68,7 @@ impl Writer { self.column_position = 0; } - pub fn clear_screen(&mut self, color: Color) { + fn clear_screen(&mut self, color: Color) { let blank = Char { ascii_character: b' ', color_code: ColorCode::new(color, color), @@ -77,29 +89,29 @@ impl Writer { self.buffer.chars[row][col] = blank; } } - pub fn write_string(&mut self, s: &str) { + fn write_string(&mut self, s: &str) { for byte in s.bytes() { self.write_byte(byte) } } - pub fn set_color(&mut self, foreground: Color, background: Color) { + fn set_color(&mut self, foreground: Color, background: Color) { self.color_code = ColorCode::new(foreground, background); } - pub fn backspace(&mut self) { + fn backspace(&mut self) { if self.column_position == 0 { return; } self.set_char(b' '); self.move_cursor(self.column_position - 1); } - pub fn cursor_back(&mut self) { + fn cursor_back(&mut self) { if self.column_position == 0 { return; } self.move_cursor(self.column_position - 1) } - pub fn cursor_front(&mut self) { + fn cursor_front(&mut self) { if self.column_position == ACTUAL_BUFFER_WIDTH { return; } diff --git a/src/main.rs b/src/main.rs index 84561a6..8f4cc1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,15 +11,16 @@ fn panic(info: &PanicInfo) -> ! { use bootloader::{entry_point, BootInfo}; use popcorn::{ - hlt_loop, init, - low_level::vga_buffer::{clear_screen, Color}, + error, hlt_loop, init, log, + low_level::vga_buffer::{send_command_to_writer, Color, CommandToWriter}, print_with_colors, println, - userspace::output::MessageToVga, log, warn, error, + userspace::output::MessageToVga, + warn, }; entry_point!(kernel_main); fn kernel_main(boot_info: &'static BootInfo) -> ! { - clear_screen(Color::Black); + send_command_to_writer(CommandToWriter::ClearScreen(Color::Black)); print_with_colors!( MessageToVga::new(Color::Yellow, Color::Black, "Welcome to the "), diff --git a/src/userspace/output.rs b/src/userspace/output.rs index dbc5f0c..a3ef763 100644 --- a/src/userspace/output.rs +++ b/src/userspace/output.rs @@ -1,4 +1,4 @@ -use crate::low_level::vga_buffer::{set_color, Color}; +use crate::low_level::vga_buffer::{send_command_to_writer, Color, CommandToWriter}; #[macro_export] macro_rules! print_with_colors { @@ -8,12 +8,12 @@ macro_rules! print_with_colors { $x.print_to_vga(); )* } - popcorn::low_level::vga_buffer::set_color(Color::White, Color::Black); - }; + $crate::low_level::vga_buffer::send_command_to_writer(popcorn::low_level::vga_buffer::CommandToWriter::SetColor(Color::White, Color::Black)); + } } #[macro_export] macro_rules! print { - ($($arg:tt)*) => ($crate::low_level::vga_buffer::print(format_args!($($arg)*))); + ($($arg:tt)*) => ($crate::low_level::vga_buffer::send_command_to_writer($crate::low_level::vga_buffer::CommandToWriter::Print(format_args!($($arg)*)))); } #[macro_export] @@ -72,7 +72,7 @@ pub struct MessageToVga<'a> { impl<'a> MessageToVga<'a> { pub fn print_to_vga(&self) { - set_color(self.foreground, self.background); + send_command_to_writer(CommandToWriter::SetColor(self.foreground, self.background)); print!("{}", self.string); } pub fn new(foreground: Color, background: Color, string: &'a str) -> Self { diff --git a/src/userspace/user_interface.rs b/src/userspace/user_interface.rs index a94188b..883de2b 100644 --- a/src/userspace/user_interface.rs +++ b/src/userspace/user_interface.rs @@ -2,25 +2,25 @@ //Backspace is implemented twice because even though it has a rawkey, its registered as Unicode. //If in some case it would be a raw key, it would cause bugs use crate::{ - low_level::vga_buffer::{backspace, cursor_back, cursor_front}, + low_level::vga_buffer::{send_command_to_writer, CommandToWriter}, print, }; pub fn handle_keypress(key: char) { match key { - '\u{8}' => backspace(), + '\u{8}' => send_command_to_writer(CommandToWriter::Backspace), _ => print!("{}", key), } } use pc_keyboard::KeyCode; pub fn handle_raw_keypress(key: KeyCode) { match key { - KeyCode::Backspace => backspace(), + KeyCode::Backspace => send_command_to_writer(CommandToWriter::Backspace), KeyCode::LShift => {} KeyCode::RShift => {} KeyCode::CapsLock => {} - KeyCode::ArrowLeft => cursor_back(), - KeyCode::ArrowRight => cursor_front(), + KeyCode::ArrowLeft => send_command_to_writer(CommandToWriter::CursorBack), + KeyCode::ArrowRight => send_command_to_writer(CommandToWriter::CursorFront), _ => print!("{:?}", key), } }