Commit b3849ddf authored by Jeremy Soller's avatar Jeremy Soller

Convert vesad to be handle based, allow O_NONBLOCK

parent 1e701391
...@@ -7,7 +7,7 @@ extern crate alloc; ...@@ -7,7 +7,7 @@ extern crate alloc;
extern crate orbclient; extern crate orbclient;
extern crate syscall; extern crate syscall;
use std::{env, mem}; use std::env;
use std::fs::File; use std::fs::File;
use std::io::{Read, Write}; use std::io::{Read, Write};
use syscall::{physmap, physunmap, Packet, SchemeMut, EVENT_READ, MAP_WRITE, MAP_WRITE_COMBINE}; use syscall::{physmap, physunmap, Packet, SchemeMut, EVENT_READ, MAP_WRITE, MAP_WRITE_COMBINE};
...@@ -68,7 +68,7 @@ fn main() { ...@@ -68,7 +68,7 @@ fn main() {
socket.read(&mut packet).expect("vesad: failed to read display scheme"); socket.read(&mut packet).expect("vesad: failed to read display scheme");
// If it is a read packet, and there is no data, block it. Otherwise, handle packet // If it is a read packet, and there is no data, block it. Otherwise, handle packet
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.will_block(packet.b) { if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.can_read(packet.b).is_none() {
blocked.push(packet); blocked.push(packet);
} else { } else {
scheme.handle(&mut packet); scheme.handle(&mut packet);
...@@ -79,7 +79,7 @@ fn main() { ...@@ -79,7 +79,7 @@ fn main() {
{ {
let mut i = 0; let mut i = 0;
while i < blocked.len() { while i < blocked.len() {
if ! scheme.will_block(blocked[i].b) { if scheme.can_read(blocked[i].b).is_some() {
let mut packet = blocked.remove(i); let mut packet = blocked.remove(i);
scheme.handle(&mut packet); scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme"); socket.write(&packet).expect("vesad: failed to write display scheme");
...@@ -90,7 +90,7 @@ fn main() { ...@@ -90,7 +90,7 @@ fn main() {
} }
for (screen_id, screen) in scheme.screens.iter() { for (screen_id, screen) in scheme.screens.iter() {
if ! screen.will_block() { if let Some(count) = screen.can_read() {
let event_packet = Packet { let event_packet = Packet {
id: 0, id: 0,
pid: 0, pid: 0,
...@@ -99,7 +99,7 @@ fn main() { ...@@ -99,7 +99,7 @@ fn main() {
a: syscall::number::SYS_FEVENT, a: syscall::number::SYS_FEVENT,
b: *screen_id, b: *screen_id,
c: EVENT_READ, c: EVENT_READ,
d: mem::size_of::<orbclient::Event>() d: count
}; };
socket.write(&event_packet).expect("vesad: failed to write display event"); socket.write(&event_packet).expect("vesad: failed to write display event");
......
...@@ -2,16 +2,30 @@ use std::collections::BTreeMap; ...@@ -2,16 +2,30 @@ use std::collections::BTreeMap;
use std::{mem, slice, str}; use std::{mem, slice, str};
use orbclient::{Event, EventOption}; use orbclient::{Event, EventOption};
use syscall::{Result, Error, EACCES, EBADF, ENOENT, SchemeMut}; use syscall::{Result, Error, EACCES, EBADF, ENOENT, O_NONBLOCK, SchemeMut};
use display::Display; use display::Display;
use screen::{Screen, GraphicScreen, TextScreen}; use screen::{Screen, GraphicScreen, TextScreen};
#[derive(Clone)]
enum HandleKind {
Input,
Screen(usize),
}
#[derive(Clone)]
struct Handle {
kind: HandleKind,
flags: usize,
}
pub struct DisplayScheme { pub struct DisplayScheme {
width: usize, width: usize,
height: usize, height: usize,
active: usize, active: usize,
pub screens: BTreeMap<usize, Box<Screen>> pub screens: BTreeMap<usize, Box<Screen>>,
next_id: usize,
handles: BTreeMap<usize, Handle>,
} }
impl DisplayScheme { impl DisplayScheme {
...@@ -32,37 +46,67 @@ impl DisplayScheme { ...@@ -32,37 +46,67 @@ impl DisplayScheme {
width: width, width: width,
height: height, height: height,
active: 1, active: 1,
screens: screens screens: screens,
next_id: 0,
handles: BTreeMap::new(),
} }
} }
pub fn will_block(&self, id: usize) -> bool { pub fn can_read(&self, id: usize) -> Option<usize> {
if let Some(screen) = self.screens.get(&id) { if let Some(handle) = self.handles.get(&id) {
screen.will_block() if let HandleKind::Screen(screen_i) = handle.kind {
} else { if let Some(screen) = self.screens.get(&screen_i) {
false match screen.can_read() {
Some(count) => return Some(count),
None => if handle.flags & O_NONBLOCK == O_NONBLOCK {
return Some(0);
} else {
return None;
}
}
}
}
} }
Some(0)
} }
} }
impl SchemeMut for DisplayScheme { impl SchemeMut for DisplayScheme {
fn open(&mut self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> { fn open(&mut self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if path == b"input" { if path == b"input" {
if uid == 0 { if uid == 0 {
Ok(0) let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle {
kind: HandleKind::Input,
flags: flags
});
Ok(id)
} else { } else {
Err(Error::new(EACCES)) Err(Error::new(EACCES))
} }
} else { } else {
let path_str = str::from_utf8(path).unwrap_or("").trim_matches('/'); let path_str = str::from_utf8(path).unwrap_or("").trim_matches('/');
let mut parts = path_str.split('/'); let mut parts = path_str.split('/');
let id = parts.next().unwrap_or("").parse::<usize>().unwrap_or(0); let screen_i = parts.next().unwrap_or("").parse::<usize>().unwrap_or(0);
if self.screens.contains_key(&id) { if self.screens.contains_key(&screen_i) {
for cmd in parts { for cmd in parts {
if cmd == "activate" { if cmd == "activate" {
self.active = id; self.active = screen_i;
} }
} }
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle {
kind: HandleKind::Screen(screen_i),
flags: flags
});
Ok(id) Ok(id)
} else { } else {
Err(Error::new(ENOENT)) Err(Error::new(ENOENT))
...@@ -71,32 +115,52 @@ impl SchemeMut for DisplayScheme { ...@@ -71,32 +115,52 @@ impl SchemeMut for DisplayScheme {
} }
fn dup(&mut self, id: usize, _buf: &[u8]) -> Result<usize> { fn dup(&mut self, id: usize, _buf: &[u8]) -> Result<usize> {
Ok(id) let handle = self.handles.get(&id).map(|handle| handle.clone()).ok_or(Error::new(EBADF))?;
let new_id = self.next_id;
self.next_id += 1;
self.handles.insert(new_id, handle.clone());
Ok(new_id)
} }
fn fevent(&mut self, id: usize, flags: usize) -> Result<usize> { fn fevent(&mut self, id: usize, flags: usize) -> Result<usize> {
if let Some(mut screen) = self.screens.get_mut(&id) { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
screen.event(flags).and(Ok(id))
} else { if let HandleKind::Screen(screen_i) = handle.kind {
Err(Error::new(EBADF)) if let Some(mut screen) = self.screens.get_mut(&screen_i) {
return screen.event(flags).and(Ok(screen_i));
}
} }
Err(Error::new(EBADF))
} }
fn fmap(&mut self, id: usize, offset: usize, size: usize) -> Result<usize> { fn fmap(&mut self, id: usize, offset: usize, size: usize) -> Result<usize> {
if let Some(screen) = self.screens.get(&id) { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
screen.map(offset, size)
} else { if let HandleKind::Screen(screen_i) = handle.kind {
Err(Error::new(EBADF)) if let Some(screen) = self.screens.get(&screen_i) {
return screen.map(offset, size);
}
} }
Err(Error::new(EBADF))
} }
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> { fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
let path_str = if id == 0 { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
format!("display:input/{}/{}", self.width, self.height)
} else if let Some(screen) = self.screens.get(&id) { let path_str = match handle.kind {
format!("display:{}/{}/{}", id, screen.width(), screen.height()) HandleKind::Input => {
} else { format!("display:input/{}/{}", self.width, self.height)
return Err(Error::new(EBADF)); },
HandleKind::Screen(screen_i) => if let Some(screen) = self.screens.get(&screen_i) {
format!("display:{}/{}/{}", screen_i, screen.width(), screen.height())
} else {
return Err(Error::new(EBADF));
}
}; };
let path = path_str.as_bytes(); let path = path_str.as_bytes();
...@@ -111,27 +175,37 @@ impl SchemeMut for DisplayScheme { ...@@ -111,27 +175,37 @@ impl SchemeMut for DisplayScheme {
} }
fn fsync(&mut self, id: usize) -> Result<usize> { fn fsync(&mut self, id: usize) -> Result<usize> {
if let Some(mut screen) = self.screens.get_mut(&id) { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if id == self.active {
screen.sync(); if let HandleKind::Screen(screen_i) = handle.kind {
if let Some(mut screen) = self.screens.get_mut(&screen_i) {
if screen_i == self.active {
screen.sync();
}
return Ok(0);
} }
Ok(0)
} else {
Err(Error::new(EBADF))
} }
Err(Error::new(EBADF))
} }
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> { fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
if let Some(mut screen) = self.screens.get_mut(&id) { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
screen.read(buf)
} else { if let HandleKind::Screen(screen_i) = handle.kind {
Err(Error::new(EBADF)) if let Some(mut screen) = self.screens.get_mut(&screen_i) {
return screen.read(buf);
}
} }
Err(Error::new(EBADF))
} }
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> { fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
if id == 0 { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if buf.len() == 1 && buf[0] >= 0xF4 {
match handle.kind {
HandleKind::Input => if buf.len() == 1 && buf[0] >= 0xF4 {
let new_active = (buf[0] - 0xF4) as usize + 1; let new_active = (buf[0] - 0xF4) as usize + 1;
if let Some(mut screen) = self.screens.get_mut(&new_active) { if let Some(mut screen) = self.screens.get_mut(&new_active) {
self.active = new_active; self.active = new_active;
...@@ -158,9 +232,9 @@ impl SchemeMut for DisplayScheme { ...@@ -158,9 +232,9 @@ impl SchemeMut for DisplayScheme {
}, },
EventOption::Resize(resize_event) => { EventOption::Resize(resize_event) => {
println!("Resizing to {}, {}", resize_event.width, resize_event.height); println!("Resizing to {}, {}", resize_event.width, resize_event.height);
for (screen_id, screen) in self.screens.iter_mut() { for (screen_i, screen) in self.screens.iter_mut() {
screen.resize(resize_event.width as usize, resize_event.height as usize); screen.resize(resize_event.width as usize, resize_event.height as usize);
if *screen_id == self.active { if *screen_i == self.active {
screen.redraw(); screen.redraw();
} }
} }
...@@ -181,23 +255,29 @@ impl SchemeMut for DisplayScheme { ...@@ -181,23 +255,29 @@ impl SchemeMut for DisplayScheme {
} }
Ok(events.len() * mem::size_of::<Event>()) Ok(events.len() * mem::size_of::<Event>())
},
HandleKind::Screen(screen_i) => if let Some(mut screen) = self.screens.get_mut(&screen_i) {
screen.write(buf, screen_i == self.active)
} else {
Err(Error::new(EBADF))
} }
} else if let Some(mut screen) = self.screens.get_mut(&id) {
screen.write(buf, id == self.active)
} else {
Err(Error::new(EBADF))
} }
} }
fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> { fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
if let Some(mut screen) = self.screens.get_mut(&id) { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
screen.seek(pos, whence)
} else { if let HandleKind::Screen(screen_i) = handle.kind {
Err(Error::new(EBADF)) if let Some(mut screen) = self.screens.get_mut(&screen_i) {
return screen.seek(pos, whence);
}
} }
Err(Error::new(EBADF))
} }
fn close(&mut self, _id: usize) -> Result<usize> { fn close(&mut self, id: usize) -> Result<usize> {
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
Ok(0) Ok(0)
} }
} }
...@@ -75,8 +75,12 @@ impl Screen for GraphicScreen { ...@@ -75,8 +75,12 @@ impl Screen for GraphicScreen {
Ok(i * mem::size_of::<Event>()) Ok(i * mem::size_of::<Event>())
} }
fn will_block(&self) -> bool { fn can_read(&self) -> Option<usize> {
self.input.is_empty() if self.input.is_empty() {
None
} else {
Some(self.input.len() * mem::size_of::<Event>())
}
} }
fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> { fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> {
......
...@@ -22,7 +22,7 @@ pub trait Screen { ...@@ -22,7 +22,7 @@ pub trait Screen {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>; fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn will_block(&self) -> bool; fn can_read(&self) -> Option<usize>;
fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize>; fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize>;
......
...@@ -167,8 +167,14 @@ impl Screen for TextScreen { ...@@ -167,8 +167,14 @@ impl Screen for TextScreen {
Ok(i) Ok(i)
} }
fn will_block(&self) -> bool { fn can_read(&self) -> Option<usize> {
self.input.is_empty() && ! self.end_of_input if self.end_of_input {
Some(0)
} else if self.input.is_empty() {
None
} else {
Some(self.input.len())
}
} }
fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> { fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment