feat(display): windows: full-screen, F1 cycles, OS bar (names, front, user); canvas-only (display-owned buffers, 4 max, reused); launchers OPEN (pm per app, terminal own), window caps minted by display; FORGET on launcher death via init courier; raster crate (font, chunked text); F-keys in input; terminal+snake on canvas; REDRAW gone
This commit is contained in:
@@ -11,8 +11,9 @@ pub mod server;
|
||||
#[path = "tests/mod.rs"]
|
||||
mod tests;
|
||||
|
||||
use libkos::display::{self, CELL_HEIGHT, CELL_WIDTH};
|
||||
use libkos::display::{self, Canvas};
|
||||
use libkos::input::{InputEvent, Key};
|
||||
use port_framebuffer::Framebuffer;
|
||||
use libkos::syscall;
|
||||
use types::badge::Badge;
|
||||
use types::bounded::CapSlot;
|
||||
@@ -23,6 +24,9 @@ use types::terminal::{KEYS_BIT, TIMER_BIT};
|
||||
const EP: CapSlot = CapSlot::const_new(0);
|
||||
const DISPLAY: CapSlot = CapSlot::const_new(1);
|
||||
|
||||
const CELL_WIDTH: usize = raster::font::WIDTH as usize;
|
||||
const CELL_HEIGHT: usize = raster::font::HEIGHT as usize;
|
||||
|
||||
const FG: Color = Color::rgb(220, 220, 220);
|
||||
const BG: Color = Color::rgb(16, 16, 24);
|
||||
/// Output is shown at most this long after it is written. The timebase is
|
||||
@@ -30,12 +34,9 @@ const BG: Color = Color::rgb(16, 16, 24);
|
||||
const FLUSH_DELAY: u64 = 20 * 10_000;
|
||||
|
||||
struct Screen {
|
||||
/// Bound to the serving thread: the display signals it with
|
||||
/// `KEYS_BIT`, the flush timer with `TIMER_BIT`.
|
||||
notify: CapSlot,
|
||||
/// The terminal's window, all of which scrolls.
|
||||
canvas: Canvas,
|
||||
timer: CapSlot,
|
||||
/// The screen's height, all of which scrolls.
|
||||
height: Dimension,
|
||||
}
|
||||
|
||||
/// A key as the line editor wants it, if it is one.
|
||||
@@ -56,21 +57,22 @@ fn at(col: usize, row: usize) -> (ScreenCoord, ScreenCoord) {
|
||||
impl server::Console for Screen {
|
||||
fn draw_row(&mut self, row: usize, text: &[u8]) {
|
||||
let (x, y) = at(0, row);
|
||||
display::draw_text(DISPLAY, x, y, FG, BG, text);
|
||||
raster::draw_text(&mut self.canvas, x, y, FG, BG, text);
|
||||
}
|
||||
|
||||
fn draw_cursor(&mut self, col: usize, row: usize, under: u8) {
|
||||
let (x, y) = at(col, row);
|
||||
display::draw_text(DISPLAY, x, y, BG, FG, &[under]);
|
||||
raster::draw_text(&mut self.canvas, x, y, BG, FG, &[under]);
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
display::flush(DISPLAY);
|
||||
self.canvas.flush();
|
||||
}
|
||||
|
||||
fn scroll(&mut self, rows: usize) {
|
||||
let by = Dimension::new(u16::try_from(rows * CELL_HEIGHT).unwrap_or(u16::MAX));
|
||||
display::scroll(DISPLAY, ScreenCoord::new(0), self.height, by, BG);
|
||||
let height = self.canvas.height();
|
||||
self.canvas.scroll_up(ScreenCoord::new(0), height, by, BG);
|
||||
}
|
||||
|
||||
fn flush_later(&mut self) {
|
||||
@@ -79,7 +81,7 @@ impl server::Console for Screen {
|
||||
}
|
||||
|
||||
fn poll_key(&mut self) -> Option<u8> {
|
||||
while let Some(event) = display::poll_input(DISPLAY) {
|
||||
while let Some(event) = display::poll_input(self.canvas.window()) {
|
||||
if let Some(key) = byte(event) {
|
||||
return Some(key);
|
||||
}
|
||||
@@ -95,11 +97,6 @@ impl server::Console for Screen {
|
||||
let _ = syscall::reply_saved(reply, words, None);
|
||||
}
|
||||
|
||||
fn take_focus(&mut self) {
|
||||
display::subscribe(DISPLAY, self.notify, Badge::new(KEYS_BIT));
|
||||
display::clear(DISPLAY, BG);
|
||||
}
|
||||
|
||||
fn interrupt(&mut self, notification: CapSlot) {
|
||||
let _ = syscall::signal(notification);
|
||||
}
|
||||
@@ -119,14 +116,17 @@ pub fn run() -> ! {
|
||||
libkos::println!("terminal: no timer, exiting");
|
||||
syscall::exit();
|
||||
};
|
||||
if !display::subscribe(DISPLAY, notify, Badge::new(KEYS_BIT)) {
|
||||
libkos::println!("terminal: no input focus, exiting");
|
||||
let Some(mut canvas) = display::open(DISPLAY, b"Terminal").and_then(|w| Canvas::attach(w.window)) else {
|
||||
libkos::println!("terminal: no window, exiting");
|
||||
syscall::exit();
|
||||
};
|
||||
if !display::subscribe(canvas.window(), notify, Badge::new(KEYS_BIT)) {
|
||||
libkos::println!("terminal: no input, exiting");
|
||||
syscall::exit();
|
||||
}
|
||||
let (w, h) = display::get_dimensions(DISPLAY);
|
||||
display::clear(DISPLAY, BG);
|
||||
let cols = w.raw() as usize / CELL_WIDTH;
|
||||
let rows = h.raw() as usize / CELL_HEIGHT;
|
||||
let mut srv = server::TerminalServer::new(Screen { notify, timer, height: h }, cols, rows);
|
||||
canvas.clear(BG);
|
||||
let cols = canvas.width().raw() as usize / CELL_WIDTH;
|
||||
let rows = canvas.height().raw() as usize / CELL_HEIGHT;
|
||||
let mut srv = server::TerminalServer::new(Screen { canvas, timer }, cols, rows);
|
||||
server_framework::serve(&mut srv, EP)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user