Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #77 from TadoTheMiner/main
Browse files Browse the repository at this point in the history
Made a cleaner interface with the vga writer
  • Loading branch information
Sparkles-Laurel authored Oct 30, 2023
2 parents 41dcdfa + d2feb9e commit 15fc4ef
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 56 deletions.
42 changes: 10 additions & 32 deletions src/low_level/vga_buffer.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -33,38 +33,16 @@ lazy_static! {
pub static ref WRITER: Mutex<Writer> =
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);
});
}
32 changes: 22 additions & 10 deletions src/low_level/vga_buffer/writer.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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();
Expand All @@ -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;
Expand All @@ -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),
Expand All @@ -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;
}
Expand Down
9 changes: 5 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 "),
Expand Down
10 changes: 5 additions & 5 deletions src/userspace/output.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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]
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions src/userspace/user_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}

0 comments on commit 15fc4ef

Please sign in to comment.