diff --git a/src/kernel/console.rs b/src/kernel/console.rs index d95bf032d..a12c40371 100644 --- a/src/kernel/console.rs +++ b/src/kernel/console.rs @@ -33,63 +33,81 @@ lazy_static! { pub static ref RAW: Mutex = Mutex::new(false); } -#[cfg(feature="vga")] pub fn has_cursor() -> bool { - true + cfg!(feature="vga") } -#[cfg(feature="serial")] -pub fn has_cursor() -> bool { - false -} - -#[cfg(feature="vga")] -pub fn clear_row() { - kernel::vga::clear_row(); +pub fn clear_row_after(x: usize) { + if cfg!(feature="vga") { + kernel::vga::clear_row_after(x); + } else { + print!("\r"); // Move cursor to begining of line + print!("\x1b[{}C", x); // Move cursor forward to position + print!("\x1b[K"); // Clear line after position + } } -#[cfg(feature="serial")] -pub fn clear_row() { - print!("\x1b[2K\r"); +pub fn cursor_position() -> (usize, usize) { + if cfg!(feature="vga") { + kernel::vga::cursor_position() + } else { + print!("\x1b[6n"); // Ask cursor position + get_char(); // ESC + get_char(); // [ + let mut x = String::new(); + let mut y = String::new(); + loop { + let c = get_char(); + if c == ';' { + break; + } else { + y.push(c); + } + } + loop { + let c = get_char(); + if c == 'R' { + break; + } else { + x.push(c); + } + } + (x.parse().unwrap_or(1), y.parse().unwrap_or(1)) + } } -#[cfg(feature="vga")] -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => ({ - $crate::kernel::vga::print_fmt(format_args!($($arg)*)); - }); +pub fn set_writer_position(x: usize, y: usize) { + if cfg!(feature="vga") { + kernel::vga::set_writer_position(x, y); + } else { + print!("\x1b[{};{}H", y + 1, x + 1); + } } -#[cfg(feature="serial")] #[macro_export] macro_rules! print { ($($arg:tt)*) => ({ - $crate::kernel::serial::print_fmt(format_args!($($arg)*)); - }); -} - -#[cfg(feature="vga")] -#[macro_export] -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"); - $crate::kernel::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); - $crate::kernel::vga::print_fmt(format_args!($($arg)*)); + if cfg!(feature="vga") { + $crate::kernel::vga::print_fmt(format_args!($($arg)*)); + } else { + $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + } }); } -#[cfg(feature="serial")] #[macro_export] 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"); - $crate::kernel::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); - $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + 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)*)); + } else { + $crate::kernel::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); + $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + } }); } diff --git a/src/kernel/keyboard.rs b/src/kernel/keyboard.rs index aaa6d76cd..e40475f9f 100644 --- a/src/kernel/keyboard.rs +++ b/src/kernel/keyboard.rs @@ -72,7 +72,7 @@ pub fn init() { kernel::idt::set_irq_handler(1, interrupt_handler); } -pub fn read_scancode() -> u8 { +fn read_scancode() -> u8 { let mut port = Port::new(0x60); unsafe { port.read() diff --git a/src/kernel/vga.rs b/src/kernel/vga.rs index 2ef3ec038..5a465c66c 100644 --- a/src/kernel/vga.rs +++ b/src/kernel/vga.rs @@ -215,26 +215,25 @@ impl Writer { self.buffer.chars[y - 1][x].write(character); } } - self.clear_row(BUFFER_HEIGHT - 1); + self.clear_row_after(0, BUFFER_HEIGHT - 1); } self.writer[0] = 0; } - /// Clears a row by overwriting it with blank characters - fn clear_row(&mut self, y: usize) { + fn clear_row_after(&mut self, x: usize, y: usize) { let blank = ScreenChar { ascii_code: b' ', color_code: self.color_code, }; - for x in 0..BUFFER_WIDTH { - self.buffer.chars[y][x].write(blank); + for i in x..BUFFER_WIDTH { + self.buffer.chars[y][i].write(blank); } } pub fn clear_screen(&mut self) { for y in 0..BUFFER_HEIGHT { - self.clear_row(y); + self.clear_row_after(0, y); } self.set_writer_position(0, 0); self.set_cursor_position(0, 0); @@ -332,11 +331,15 @@ pub fn clear_screen() { } pub fn clear_row() { + clear_row_after(0); +} + +pub fn clear_row_after(x: usize) { let (_, y) = writer_position(); interrupts::without_interrupts(|| { - WRITER.lock().clear_row(y); + WRITER.lock().clear_row_after(x, y); }); - set_writer_position(0, y); + set_writer_position(x, y); } pub fn screen_width() -> usize { diff --git a/src/user/shell.rs b/src/user/shell.rs index 6aa0662f5..8a7418cfa 100644 --- a/src/user/shell.rs +++ b/src/user/shell.rs @@ -121,8 +121,9 @@ impl Shell { self.history_index -= 1; } let cmd = &self.history[self.history_index]; - kernel::vga::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + kernel::console::clear_row_after(n + cmd.len()); + kernel::vga::set_writer_position(n, y); print!("{}", cmd); } }, @@ -135,8 +136,9 @@ impl Shell { } else { &self.cmd }; - kernel::vga::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + kernel::console::clear_row_after(n + cmd.len()); + kernel::vga::set_writer_position(n, y); print!("{}", cmd); } }, @@ -170,9 +172,7 @@ impl Shell { self.cmd.clear(); self.cmd.push_str(before_cursor); self.cmd.push_str(after_cursor); - kernel::vga::clear_row(); - self.print_prompt(); - print!("{}", self.cmd); + print!("{}{} ", c, after_cursor); kernel::vga::set_cursor_position(x - 1, y); kernel::vga::set_writer_position(x - 1, y); } @@ -193,9 +193,7 @@ impl Shell { self.cmd.push_str(before_cursor); self.cmd.push(c); self.cmd.push_str(after_cursor); - kernel::vga::clear_row(); - self.print_prompt(); - print!("{}", self.cmd); + print!("{}{}", c, after_cursor); kernel::vga::set_cursor_position(x + 1, y); kernel::vga::set_writer_position(x + 1, y); } else { @@ -293,8 +291,10 @@ impl Shell { args[i] = &self.autocomplete[self.autocomplete_index]; let cmd = args.join(" "); - kernel::console::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + let (_, y) = kernel::console::cursor_position(); + kernel::console::clear_row_after(n + cmd.len()); + kernel::console::set_writer_position(n, y); print!("{}", cmd); }