2016-10-08 04:18:05 +02:00
|
|
|
use std::cell::{Cell, RefCell};
|
|
|
|
use std::collections::BTreeMap;
|
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
2016-10-14 01:21:42 +02:00
|
|
|
use std::{mem, slice, str};
|
2016-10-08 04:18:05 +02:00
|
|
|
|
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
2016-10-14 01:21:42 +02:00
|
|
|
use orbclient::{Event, EventOption};
|
|
|
|
use syscall::{Result, Error, EACCES, EBADF, ENOENT, Scheme};
|
2016-10-08 04:18:05 +02:00
|
|
|
|
|
|
|
use display::Display;
|
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
2016-10-14 01:21:42 +02:00
|
|
|
use screen::{Screen, GraphicScreen, TextScreen};
|
2016-10-08 04:18:05 +02:00
|
|
|
|
|
|
|
pub struct DisplayScheme {
|
|
|
|
width: usize,
|
|
|
|
height: usize,
|
|
|
|
onscreen: usize,
|
|
|
|
active: Cell<usize>,
|
2016-10-15 02:22:57 +02:00
|
|
|
next_screen: Cell<usize>,
|
2016-10-15 04:12:21 +02:00
|
|
|
pub screens: RefCell<BTreeMap<usize, Box<Screen>>>
|
2016-10-08 04:18:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DisplayScheme {
|
2016-10-15 02:22:57 +02:00
|
|
|
pub fn new(width: usize, height: usize, onscreen: usize, spec: &[bool]) -> DisplayScheme {
|
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
2016-10-14 01:21:42 +02:00
|
|
|
let mut screens: BTreeMap<usize, Box<Screen>> = BTreeMap::new();
|
2016-10-15 02:22:57 +02:00
|
|
|
|
|
|
|
let mut screen_i = 1;
|
|
|
|
for &screen_type in spec.iter() {
|
|
|
|
if screen_type {
|
|
|
|
screens.insert(screen_i, Box::new(GraphicScreen::new(Display::new(width, height, onscreen))));
|
|
|
|
} else {
|
|
|
|
screens.insert(screen_i, Box::new(TextScreen::new(Display::new(width, height, onscreen))));
|
|
|
|
}
|
|
|
|
screen_i += 1;
|
|
|
|
}
|
2016-10-08 04:18:05 +02:00
|
|
|
|
|
|
|
DisplayScheme {
|
|
|
|
width: width,
|
|
|
|
height: height,
|
|
|
|
onscreen: onscreen,
|
|
|
|
active: Cell::new(1),
|
2016-10-15 02:22:57 +02:00
|
|
|
next_screen: Cell::new(screen_i),
|
2016-10-08 04:18:05 +02:00
|
|
|
screens: RefCell::new(screens)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn will_block(&self, id: usize) -> bool {
|
|
|
|
let screens = self.screens.borrow();
|
|
|
|
if let Some(screen) = screens.get(&id) {
|
|
|
|
screen.will_block()
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Scheme for DisplayScheme {
|
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
2016-10-14 01:21:42 +02:00
|
|
|
fn open(&self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
2016-10-08 04:18:05 +02:00
|
|
|
if path == b"input" {
|
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
2016-10-14 01:21:42 +02:00
|
|
|
if uid == 0 {
|
|
|
|
Ok(0)
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EACCES))
|
|
|
|
}
|
2016-10-08 04:18:05 +02:00
|
|
|
} else {
|
|
|
|
let path_str = str::from_utf8(path).unwrap_or("");
|
|
|
|
let id = path_str.parse::<usize>().unwrap_or(0);
|
|
|
|
if self.screens.borrow().contains_key(&id) {
|
|
|
|
Ok(id)
|
|
|
|
} else {
|
|
|
|
Err(Error::new(ENOENT))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn dup(&self, id: usize) -> Result<usize> {
|
|
|
|
Ok(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2016-10-15 04:12:21 +02:00
|
|
|
screen.event(flags).and(Ok(id))
|
2016-10-08 04:18:05 +02:00
|
|
|
} else {
|
|
|
|
Err(Error::new(EBADF))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
|
|
|
let screens = self.screens.borrow();
|
|
|
|
let path_str = if id == 0 {
|
|
|
|
format!("display:input")
|
|
|
|
} else if let Some(screen) = screens.get(&id) {
|
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
2016-10-14 01:21:42 +02:00
|
|
|
format!("display:{}/{}/{}", id, screen.width(), screen.height())
|
2016-10-08 04:18:05 +02:00
|
|
|
} else {
|
|
|
|
return Err(Error::new(EBADF));
|
|
|
|
};
|
|
|
|
|
|
|
|
let path = path_str.as_bytes();
|
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
while i < buf.len() && i < path.len() {
|
|
|
|
buf[i] = path[i];
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fsync(&self, id: usize) -> Result<usize> {
|
|
|
|
let mut screens = self.screens.borrow_mut();
|
|
|
|
if let Some(mut screen) = screens.get_mut(&id) {
|
|
|
|
if id == self.active.get() {
|
|
|
|
screen.sync();
|
|
|
|
}
|
|
|
|
Ok(0)
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EBADF))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
|
|
|
let mut screens = self.screens.borrow_mut();
|
|
|
|
if let Some(mut screen) = screens.get_mut(&id) {
|
|
|
|
screen.read(buf)
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EBADF))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
|
|
|
|
let mut screens = self.screens.borrow_mut();
|
|
|
|
if id == 0 {
|
|
|
|
if buf.len() == 1 && buf[0] >= 0xF4 {
|
|
|
|
let new_active = (buf[0] - 0xF4) as usize + 1;
|
|
|
|
if let Some(mut screen) = screens.get_mut(&new_active) {
|
|
|
|
self.active.set(new_active);
|
|
|
|
screen.redraw();
|
|
|
|
}
|
|
|
|
Ok(1)
|
|
|
|
} else {
|
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
2016-10-14 01:21:42 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2016-10-08 04:18:05 +02:00
|
|
|
}
|
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
2016-10-14 01:21:42 +02:00
|
|
|
|
|
|
|
Ok(events.len() * mem::size_of::<Event>())
|
2016-10-08 04:18:05 +02:00
|
|
|
}
|
|
|
|
} else if let Some(mut screen) = screens.get_mut(&id) {
|
|
|
|
screen.write(buf, id == self.active.get())
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EBADF))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
2016-10-14 01:21:42 +02:00
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-08 04:18:05 +02:00
|
|
|
fn close(&self, _id: usize) -> Result<usize> {
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
}
|