Orbital (#16)
* 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:
parent
372d44f88c
commit
224c43f761
92 changed files with 3415 additions and 473 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue