parent
0d1afaa016
commit
b49211f24e
23 changed files with 459 additions and 239 deletions
1
drivers/vesad/src/screen/graphic.rs
Normal file
1
drivers/vesad/src/screen/graphic.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub struct GraphicScreen;
|
10
drivers/vesad/src/screen/mod.rs
Normal file
10
drivers/vesad/src/screen/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
pub use self::graphic::GraphicScreen;
|
||||
pub use self::text::TextScreen;
|
||||
|
||||
mod graphic;
|
||||
mod text;
|
||||
|
||||
pub enum Screen {
|
||||
Graphic(GraphicScreen),
|
||||
Text(TextScreen)
|
||||
}
|
149
drivers/vesad/src/screen/text.rs
Normal file
149
drivers/vesad/src/screen/text.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
extern crate ransid;
|
||||
|
||||
use std::collections::{BTreeSet, VecDeque};
|
||||
|
||||
use self::ransid::{Console, Event};
|
||||
use syscall::Result;
|
||||
|
||||
use display::Display;
|
||||
|
||||
pub struct TextScreen {
|
||||
pub console: Console,
|
||||
pub display: Display,
|
||||
pub changed: BTreeSet<usize>,
|
||||
pub input: VecDeque<u8>,
|
||||
pub end_of_input: bool,
|
||||
pub cooked: VecDeque<u8>,
|
||||
pub requested: usize
|
||||
}
|
||||
|
||||
impl TextScreen {
|
||||
pub fn new(display: Display) -> TextScreen {
|
||||
TextScreen {
|
||||
console: Console::new(display.width/8, display.height/16),
|
||||
display: display,
|
||||
changed: BTreeSet::new(),
|
||||
input: VecDeque::new(),
|
||||
end_of_input: false,
|
||||
cooked: VecDeque::new(),
|
||||
requested: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn input(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
if self.console.raw_mode {
|
||||
for &b in buf.iter() {
|
||||
self.input.push_back(b);
|
||||
}
|
||||
} else {
|
||||
for &b in buf.iter() {
|
||||
match b {
|
||||
b'\x03' => {
|
||||
self.end_of_input = true;
|
||||
self.write(b"^C\n", true)?;
|
||||
},
|
||||
b'\x08' | b'\x7F' => {
|
||||
if let Some(_c) = self.cooked.pop_back() {
|
||||
self.write(b"\x08", true)?;
|
||||
}
|
||||
},
|
||||
b'\n' | b'\r' => {
|
||||
self.cooked.push_back(b);
|
||||
while let Some(c) = self.cooked.pop_front() {
|
||||
self.input.push_back(c);
|
||||
}
|
||||
self.write(b"\n", true)?;
|
||||
},
|
||||
_ => {
|
||||
self.cooked.push_back(b);
|
||||
self.write(&[b], true)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
let mut i = 0;
|
||||
|
||||
while i < buf.len() && ! self.input.is_empty() {
|
||||
buf[i] = self.input.pop_front().unwrap();
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
self.end_of_input = false;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
pub fn will_block(&self) -> bool {
|
||||
self.input.is_empty() && ! self.end_of_input
|
||||
}
|
||||
|
||||
pub fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> {
|
||||
if self.console.cursor && self.console.x < self.console.w && self.console.y < self.console.h {
|
||||
let x = self.console.x;
|
||||
let y = self.console.y;
|
||||
let color = self.console.background;
|
||||
self.display.rect(x * 8, y * 16, 8, 16, color.data);
|
||||
self.changed.insert(y);
|
||||
}
|
||||
|
||||
{
|
||||
let display = &mut self.display;
|
||||
let changed = &mut self.changed;
|
||||
self.console.write(buf, |event| {
|
||||
match event {
|
||||
Event::Char { x, y, c, color, bold, .. } => {
|
||||
display.char(x * 8, y * 16, c, color.data, bold, false);
|
||||
changed.insert(y);
|
||||
},
|
||||
Event::Rect { x, y, w, h, color } => {
|
||||
display.rect(x * 8, y * 16, w * 8, h * 16, color.data);
|
||||
for y2 in y..y + h {
|
||||
changed.insert(y2);
|
||||
}
|
||||
},
|
||||
Event::Scroll { rows, color } => {
|
||||
display.scroll(rows * 16, color.data);
|
||||
for y in 0..display.height/16 {
|
||||
changed.insert(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if self.console.cursor && self.console.x < self.console.w && self.console.y < self.console.h {
|
||||
let x = self.console.x;
|
||||
let y = self.console.y;
|
||||
let color = self.console.foreground;
|
||||
self.display.rect(x * 8, y * 16, 8, 16, color.data);
|
||||
self.changed.insert(y);
|
||||
}
|
||||
|
||||
if ! self.console.raw_mode && sync {
|
||||
self.sync();
|
||||
}
|
||||
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
pub fn sync(&mut self) {
|
||||
let width = self.display.width;
|
||||
for change in self.changed.iter() {
|
||||
self.display.sync(0, change * 16, width, 16);
|
||||
}
|
||||
self.changed.clear();
|
||||
}
|
||||
|
||||
pub fn redraw(&mut self) {
|
||||
let width = self.display.width;
|
||||
let height = self.display.height;
|
||||
self.display.sync(0, 0, width, height);
|
||||
self.changed.clear();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue