* Port previous ethernet scheme

* Add ipd

* Fix initfs rebuilds, use QEMU user networking addresses in ipd

* Add tcp/udp, netutils, dns, and network config

* Add fsync to network driver

* Add dns, router, subnet by default

* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks

* Add orbital server, WIP

* Add futex

* Add orbutils and orbital

* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad

* Add orbital assets

* Update orbital

* Update to add login manager

* Add blocking primitives, block for most things except waitpid, update orbital

* Wait in waitpid and IRQ, improvements for other waits

* Fevent in root scheme

* WIP: Switch to using fevent

* Reorganize

* Event based e1000d driver

* Superuser-only access to some network schemes, display, and disk

* Superuser root and irq schemes

* Fix orbital
This commit is contained in:
Jeremy Soller 2016-10-13 17:21:42 -06:00 committed by GitHub
parent 372d44f88c
commit 224c43f761
92 changed files with 3415 additions and 473 deletions

View file

@ -3,6 +3,7 @@ name = "vesad"
version = "0.1.0"
[dependencies]
orbclient = "0.1"
ransid = { git = "https://github.com/redox-os/ransid.git", branch = "new_api" }
rusttype = { git = "https://github.com/dylanede/rusttype.git", optional = true }
syscall = { path = "../../syscall/" }

View file

@ -4,6 +4,7 @@
#![feature(question_mark)]
extern crate alloc;
extern crate orbclient;
extern crate syscall;
use std::fs::File;

View file

@ -1,26 +1,26 @@
use std::cell::{Cell, RefCell};
use std::collections::BTreeMap;
use std::str;
use std::{mem, slice, str};
use syscall::{Result, Error, EBADF, ENOENT, Scheme};
use orbclient::{Event, EventOption};
use syscall::{Result, Error, EACCES, EBADF, ENOENT, Scheme};
use display::Display;
use screen::TextScreen;
use screen::{Screen, GraphicScreen, TextScreen};
pub struct DisplayScheme {
width: usize,
height: usize,
onscreen: usize,
active: Cell<usize>,
screens: RefCell<BTreeMap<usize, TextScreen>>
screens: RefCell<BTreeMap<usize, Box<Screen>>>
}
impl DisplayScheme {
pub fn new(width: usize, height: usize, onscreen: usize) -> DisplayScheme {
let mut screens = BTreeMap::new();
for i in 1..7 {
screens.insert(i, TextScreen::new(Display::new(width, height, onscreen)));
}
let mut screens: BTreeMap<usize, Box<Screen>> = BTreeMap::new();
screens.insert(1, Box::new(TextScreen::new(Display::new(width, height, onscreen))));
screens.insert(2, Box::new(GraphicScreen::new(Display::new(width, height, onscreen))));
DisplayScheme {
width: width,
@ -42,9 +42,13 @@ impl DisplayScheme {
}
impl Scheme for DisplayScheme {
fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if path == b"input" {
Ok(0)
if uid == 0 {
Ok(0)
} else {
Err(Error::new(EACCES))
}
} else {
let path_str = str::from_utf8(path).unwrap_or("");
let id = path_str.parse::<usize>().unwrap_or(0);
@ -63,9 +67,7 @@ impl Scheme for DisplayScheme {
fn fevent(&self, id: usize, flags: usize) -> Result<usize> {
let mut screens = self.screens.borrow_mut();
if let Some(mut screen) = screens.get_mut(&id) {
println!("fevent {:X}", flags);
screen.requested = flags;
Ok(0)
screen.event(flags)
} else {
Err(Error::new(EBADF))
}
@ -76,7 +78,7 @@ impl Scheme for DisplayScheme {
let path_str = if id == 0 {
format!("display:input")
} else if let Some(screen) = screens.get(&id) {
format!("display:{}/{}/{}", id, screen.console.w, screen.console.h)
format!("display:{}/{}/{}", id, screen.width(), screen.height())
} else {
return Err(Error::new(EBADF));
};
@ -124,11 +126,39 @@ impl Scheme for DisplayScheme {
}
Ok(1)
} else {
if let Some(mut screen) = screens.get_mut(&self.active.get()) {
screen.input(buf)
} else {
Err(Error::new(EBADF))
let events = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Event, buf.len()/mem::size_of::<Event>()) };
for event in events.iter() {
let new_active_opt = if let EventOption::Key(key_event) = event.to_option() {
match key_event.scancode {
f @ 0x3B ... 0x44 => { // F1 through F10
Some((f - 0x3A) as usize)
},
0x57 => { // F11
Some(11)
},
0x58 => { // F12
Some(12)
},
_ => None
}
} else {
None
};
if let Some(new_active) = new_active_opt {
if let Some(mut screen) = screens.get_mut(&new_active) {
self.active.set(new_active);
screen.redraw();
}
} else {
if let Some(mut screen) = screens.get_mut(&self.active.get()) {
screen.input(event);
}
}
}
Ok(events.len() * mem::size_of::<Event>())
}
} else if let Some(mut screen) = screens.get_mut(&id) {
screen.write(buf, id == self.active.get())
@ -137,6 +167,15 @@ impl Scheme for DisplayScheme {
}
}
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
let mut screens = self.screens.borrow_mut();
if let Some(mut screen) = screens.get_mut(&id) {
screen.seek(pos, whence)
} else {
Err(Error::new(EBADF))
}
}
fn close(&self, _id: usize) -> Result<usize> {
Ok(0)
}

View file

@ -1 +1,118 @@
pub struct GraphicScreen;
use std::collections::VecDeque;
use std::{cmp, mem, slice};
use orbclient::{Event, EventOption};
use syscall::error::*;
use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END};
use display::Display;
use primitive::fast_copy;
use screen::Screen;
pub struct GraphicScreen {
pub display: Display,
pub seek: usize,
pub mouse_x: i32,
pub mouse_y: i32,
pub input: VecDeque<Event>,
pub requested: usize
}
impl GraphicScreen {
pub fn new(display: Display) -> GraphicScreen {
GraphicScreen {
display: display,
seek: 0,
mouse_x: 0,
mouse_y: 0,
input: VecDeque::new(),
requested: 0
}
}
}
impl Screen for GraphicScreen {
fn width(&self) -> usize {
self.display.width
}
fn height(&self) -> usize {
self.display.height
}
fn event(&mut self, flags: usize) -> Result<usize> {
self.requested = flags;
Ok(0)
}
fn input(&mut self, event: &Event) {
if let EventOption::Mouse(mut mouse_event) = event.to_option() {
let x = cmp::max(0, cmp::min(self.display.width as i32, self.mouse_x + mouse_event.x));
let y = cmp::max(0, cmp::min(self.display.height as i32, self.mouse_y + mouse_event.y));
mouse_event.x = x;
self.mouse_x = x;
mouse_event.y = y;
self.mouse_y = y;
self.input.push_back(mouse_event.to_event());
} else {
self.input.push_back(*event);
}
}
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut i = 0;
let event_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Event, buf.len()/mem::size_of::<Event>()) };
while i < event_buf.len() && ! self.input.is_empty() {
event_buf[i] = self.input.pop_front().unwrap();
i += 1;
}
Ok(i * mem::size_of::<Event>())
}
fn will_block(&self) -> bool {
self.input.is_empty()
}
fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> {
let size = cmp::max(0, cmp::min(self.display.offscreen.len() as isize - self.seek as isize, (buf.len()/4) as isize)) as usize;
if size > 0 {
unsafe {
fast_copy(self.display.offscreen.as_mut_ptr().offset(self.seek as isize) as *mut u8, buf.as_ptr(), size * 4);
if sync {
fast_copy(self.display.onscreen.as_mut_ptr().offset(self.seek as isize) as *mut u8, buf.as_ptr(), size * 4);
}
}
}
Ok(size * 4)
}
fn seek(&mut self, pos: usize, whence: usize) -> Result<usize> {
let size = self.display.offscreen.len();
self.seek = match whence {
SEEK_SET => cmp::min(size, (pos/4)),
SEEK_CUR => cmp::max(0, cmp::min(size as isize, self.seek as isize + (pos/4) as isize)) as usize,
SEEK_END => cmp::max(0, cmp::min(size as isize, size as isize + (pos/4) as isize)) as usize,
_ => return Err(Error::new(EINVAL))
};
Ok(self.seek * 4)
}
fn sync(&mut self) {
self.redraw();
}
fn redraw(&mut self) {
let width = self.display.width;
let height = self.display.height;
self.display.sync(0, 0, width, height);
}
}

View file

@ -1,10 +1,30 @@
pub use self::graphic::GraphicScreen;
pub use self::text::TextScreen;
use orbclient::Event;
use syscall::Result;
mod graphic;
mod text;
pub enum Screen {
Graphic(GraphicScreen),
Text(TextScreen)
pub trait Screen {
fn width(&self) -> usize;
fn height(&self) -> usize;
fn event(&mut self, flags: usize) -> Result<usize>;
fn input(&mut self, event: &Event);
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn will_block(&self) -> bool;
fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize>;
fn seek(&mut self, pos: usize, whence: usize) -> Result<usize>;
fn sync(&mut self);
fn redraw(&mut self);
}

View file

@ -2,15 +2,17 @@ extern crate ransid;
use std::collections::{BTreeSet, VecDeque};
use self::ransid::{Console, Event};
use orbclient::{Event, EventOption};
use syscall::Result;
use display::Display;
use screen::Screen;
pub struct TextScreen {
pub console: Console,
pub console: ransid::Console,
pub display: Display,
pub changed: BTreeSet<usize>,
pub ctrl: bool,
pub input: VecDeque<u8>,
pub end_of_input: bool,
pub cooked: VecDeque<u8>,
@ -20,17 +22,88 @@ pub struct TextScreen {
impl TextScreen {
pub fn new(display: Display) -> TextScreen {
TextScreen {
console: Console::new(display.width/8, display.height/16),
console: ransid::Console::new(display.width/8, display.height/16),
display: display,
changed: BTreeSet::new(),
ctrl: false,
input: VecDeque::new(),
end_of_input: false,
cooked: VecDeque::new(),
requested: 0
}
}
}
impl Screen for TextScreen {
fn width(&self) -> usize {
self.console.w
}
fn height(&self) -> usize {
self.console.h
}
fn event(&mut self, flags: usize) -> Result<usize> {
self.requested = flags;
Ok(0)
}
fn input(&mut self, event: &Event) {
let mut buf = vec![];
match event.to_option() {
EventOption::Key(key_event) => {
if key_event.scancode == 0x1D {
self.ctrl = key_event.pressed;
} else if key_event.pressed {
match key_event.scancode {
0x47 => { // Home
buf.extend_from_slice(b"\x1B[H");
},
0x48 => { // Up
buf.extend_from_slice(b"\x1B[A");
},
0x49 => { // Page up
buf.extend_from_slice(b"\x1B[5~");
},
0x4B => { // Left
buf.extend_from_slice(b"\x1B[D");
},
0x4D => { // Right
buf.extend_from_slice(b"\x1B[C");
},
0x4F => { // End
buf.extend_from_slice(b"\x1B[F");
},
0x50 => { // Down
buf.extend_from_slice(b"\x1B[B");
},
0x51 => { // Page down
buf.extend_from_slice(b"\x1B[6~");
},
0x52 => { // Insert
buf.extend_from_slice(b"\x1B[2~");
},
0x53 => { // Delete
buf.extend_from_slice(b"\x1B[3~");
},
_ => {
let c = match key_event.character {
c @ 'A' ... 'Z' if self.ctrl => ((c as u8 - b'A') + b'\x01') as char,
c @ 'a' ... 'z' if self.ctrl => ((c as u8 - b'a') + b'\x01') as char,
c => c
};
if c != '\0' {
buf.extend_from_slice(&[c as u8]);
}
}
}
}
},
_ => () //TODO: Mouse in terminal
}
pub fn input(&mut self, buf: &[u8]) -> Result<usize> {
if self.console.raw_mode {
for &b in buf.iter() {
self.input.push_back(b);
@ -40,11 +113,11 @@ impl TextScreen {
match b {
b'\x03' => {
self.end_of_input = true;
self.write(b"^C\n", true)?;
let _ = self.write(b"^C\n", true);
},
b'\x08' | b'\x7F' => {
if let Some(_c) = self.cooked.pop_back() {
self.write(b"\x08", true)?;
let _ = self.write(b"\x08", true);
}
},
b'\n' | b'\r' => {
@ -52,19 +125,18 @@ impl TextScreen {
while let Some(c) = self.cooked.pop_front() {
self.input.push_back(c);
}
self.write(b"\n", true)?;
let _ = self.write(b"\n", true);
},
_ => {
self.cooked.push_back(b);
self.write(&[b], true)?;
let _ = self.write(&[b], true);
}
}
}
}
Ok(buf.len())
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut i = 0;
while i < buf.len() && ! self.input.is_empty() {
@ -79,11 +151,11 @@ impl TextScreen {
Ok(i)
}
pub fn will_block(&self) -> bool {
fn will_block(&self) -> bool {
self.input.is_empty() && ! self.end_of_input
}
pub fn write(&mut self, buf: &[u8], sync: bool) -> Result<usize> {
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;
@ -97,17 +169,17 @@ impl TextScreen {
let changed = &mut self.changed;
self.console.write(buf, |event| {
match event {
Event::Char { x, y, c, color, bold, .. } => {
ransid::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 } => {
ransid::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 } => {
ransid::Event::Scroll { rows, color } => {
display.scroll(rows * 16, color.data);
for y in 0..display.height/16 {
changed.insert(y);
@ -132,7 +204,11 @@ impl TextScreen {
Ok(buf.len())
}
pub fn sync(&mut self) {
fn seek(&mut self, pos: usize, whence: usize) -> Result<usize> {
Ok(0)
}
fn sync(&mut self) {
let width = self.display.width;
for change in self.changed.iter() {
self.display.sync(0, change * 16, width, 16);
@ -140,7 +216,7 @@ impl TextScreen {
self.changed.clear();
}
pub fn redraw(&mut self) {
fn redraw(&mut self) {
let width = self.display.width;
let height = self.display.height;
self.display.sync(0, 0, width, height);