redox/drivers/vesad/src/main.rs

148 lines
4.8 KiB
Rust
Raw Normal View History

#![feature(alloc)]
#![feature(asm)]
#![feature(heap_api)]
2016-09-21 20:18:48 +02:00
#![feature(question_mark)]
extern crate alloc;
2016-09-21 20:18:48 +02:00
extern crate ransid;
extern crate syscall;
2016-09-21 20:18:48 +02:00
use std::cell::RefCell;
use std::collections::VecDeque;
use std::fs::File;
2016-09-21 20:18:48 +02:00
use std::io::{Read, Write};
use std::{slice, thread};
2016-09-21 20:18:48 +02:00
use ransid::{Console, Event};
use syscall::{physmap, physunmap, Packet, Result, Scheme, MAP_WRITE, MAP_WRITE_COMBINE};
use display::Display;
use mode_info::VBEModeInfo;
use primitive::fast_set64;
pub mod display;
pub mod mode_info;
pub mod primitive;
2016-09-21 20:18:48 +02:00
struct DisplayScheme {
console: RefCell<Console>,
display: RefCell<Display>,
input: RefCell<VecDeque<u8>>
2016-09-21 20:18:48 +02:00
}
impl Scheme for DisplayScheme {
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
if path == b"input" {
Ok(1)
} else {
Ok(0)
}
2016-09-21 20:18:48 +02:00
}
fn dup(&self, id: usize) -> Result<usize> {
Ok(id)
2016-09-21 20:18:48 +02:00
}
fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0)
}
fn read(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
let mut i = 0;
let mut input = self.input.borrow_mut();
while i < buf.len() && ! input.is_empty() {
buf[i] = input.pop_front().unwrap();
i += 1;
}
Ok(i)
}
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
if id == 1 {
let mut input = self.input.borrow_mut();
for &b in buf.iter() {
input.push_back(b);
2016-09-21 20:18:48 +02:00
}
Ok(buf.len())
} else {
let mut display = self.display.borrow_mut();
2016-09-23 01:11:42 +02:00
let mut console = self.console.borrow_mut();
if console.x < console.w && console.y < console.h {
display.rect(console.x * 8, console.y * 16, 8, 16, 0);
}
console.write(buf, |event| {
match event {
2016-09-23 00:15:38 +02:00
Event::Char { x, y, c, color, bold, .. } => display.char(x * 8, y * 16, c, color.data, bold, false),
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data),
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data)
}
});
2016-09-23 01:11:42 +02:00
if console.x < console.w && console.y < console.h {
display.rect(console.x * 8, console.y * 16, 8, 16, 0xFFFFFF);
}
Ok(buf.len())
}
2016-09-21 20:18:48 +02:00
}
fn close(&self, _id: usize) -> Result<usize> {
2016-09-21 20:18:48 +02:00
Ok(0)
}
}
fn main() {
let width;
let height;
let physbaseptr;
{
let mode_info = unsafe { &*(physmap(0x5200, 4096, 0).expect("vesad: failed to map VBE info") as *const VBEModeInfo) };
width = mode_info.xresolution as usize;
height = mode_info.yresolution as usize;
physbaseptr = mode_info.physbaseptr as usize;
unsafe { let _ = physunmap(mode_info as *const _ as usize); }
}
if physbaseptr > 0 {
thread::spawn(move || {
2016-09-21 05:56:40 +02:00
let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
2016-09-21 20:18:48 +02:00
let size = width * height;
let onscreen = unsafe { physmap(physbaseptr as usize, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };
let offscreen = unsafe { alloc::heap::allocate(size * 4, 4096) };
unsafe { fast_set64(offscreen as *mut u64, 0, size/2) };
2016-09-21 20:18:48 +02:00
let scheme = DisplayScheme {
console: RefCell::new(Console::new(width/8, height/16)),
display: RefCell::new(Display::new(width, height,
unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) },
unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }
)),
input: RefCell::new(VecDeque::new())
2016-09-21 20:18:48 +02:00
};
let mut blocked = VecDeque::new();
2016-09-21 20:18:48 +02:00
loop {
let mut packet = Packet::default();
socket.read(&mut packet).expect("vesad: failed to read display scheme");
2016-09-21 20:18:48 +02:00
//println!("vesad: {:?}", packet);
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.input.borrow().is_empty() {
blocked.push_back(packet);
} else {
scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme");
}
while ! scheme.input.borrow().is_empty() {
if let Some(mut packet) = blocked.pop_front() {
scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme");
}
}
2016-09-21 20:18:48 +02:00
}
});
}
}