Add wnohang, make PS/2 driver write input to display scheme, which then passes it to the shell
This commit is contained in:
parent
046236c10f
commit
76b0c7eeea
6
Makefile
6
Makefile
|
@ -24,12 +24,12 @@ all: $(KBUILD)/harddrive.bin
|
|||
clean:
|
||||
cargo clean
|
||||
cargo clean --manifest-path libstd/Cargo.toml
|
||||
cargo clean --manifest-path init/Cargo.toml
|
||||
cargo clean --manifest-path ion/Cargo.toml
|
||||
cargo clean --manifest-path login/Cargo.toml
|
||||
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
||||
cargo clean --manifest-path drivers/pcid/Cargo.toml
|
||||
cargo clean --manifest-path drivers/vesad/Cargo.toml
|
||||
cargo clean --manifest-path programs/init/Cargo.toml
|
||||
cargo clean --manifest-path programs/ion/Cargo.toml
|
||||
cargo clean --manifest-path programs/login/Cargo.toml
|
||||
cargo clean --manifest-path schemes/example/Cargo.toml
|
||||
rm -rf initfs/bin
|
||||
rm -rf build
|
||||
|
|
|
@ -42,7 +42,7 @@ impl Mapper {
|
|||
|
||||
/// Map a page to the next free frame
|
||||
pub fn map(&mut self, page: Page, flags: EntryFlags) {
|
||||
let frame = allocate_frame().expect("out of memory");
|
||||
let frame = allocate_frame().expect("out of frames");
|
||||
self.map_to(page, frame, flags)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@ use keymap;
|
|||
|
||||
pub fn keyboard() {
|
||||
let mut file = File::open("irq:1").expect("ps2d: failed to open irq:1");
|
||||
let mut input = File::open("display:input").expect("ps2d: failed to open display:input");
|
||||
|
||||
let mut lshift = false;
|
||||
let mut rshift = false;
|
||||
loop {
|
||||
let mut irqs = [0; 8];
|
||||
if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::<usize>() {
|
||||
|
@ -16,17 +19,25 @@ pub fn keyboard() {
|
|||
asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile");
|
||||
}
|
||||
|
||||
file.write(&irqs).expect("ps2d: failed to write irq:1");
|
||||
|
||||
let (scancode, pressed) = if data >= 0x80 {
|
||||
(data - 0x80, false)
|
||||
} else {
|
||||
(data, true)
|
||||
};
|
||||
|
||||
if pressed {
|
||||
print!("{}", keymap::get_char(scancode));
|
||||
if scancode == 0x2A {
|
||||
lshift = pressed;
|
||||
} else if scancode == 0x36 {
|
||||
rshift = pressed;
|
||||
} else if pressed {
|
||||
let c = keymap::get_char(scancode, lshift || rshift);
|
||||
if c != '\0' {
|
||||
print!("{}", c);
|
||||
input.write(&[c as u8]).expect("ps2d: failed to write input");
|
||||
}
|
||||
}
|
||||
|
||||
file.write(&irqs).expect("ps2d: failed to write irq:1");
|
||||
} else {
|
||||
thread::yield_now();
|
||||
}
|
||||
|
|
|
@ -1,67 +1,71 @@
|
|||
static ENGLISH: [[char; 3]; 58] = [
|
||||
['\0', '\0', '\0'],
|
||||
['\x1B', '\x1B', '\x1B'],
|
||||
['1', '!', '1'],
|
||||
['2', '@', '2'],
|
||||
['3', '#', '3'],
|
||||
['4', '$', '4'],
|
||||
['5', '%', '5'],
|
||||
['6', '^', '6'],
|
||||
['7', '&', '7'],
|
||||
['8', '*', '8'],
|
||||
['9', '(', '9'],
|
||||
['0', ')', '0'],
|
||||
['-', '_', '-'],
|
||||
['=', '+', '='],
|
||||
['\0', '\0', '\0'],
|
||||
['\t', '\t', '\t'],
|
||||
['q', 'Q', 'q'],
|
||||
['w', 'W', 'w'],
|
||||
['e', 'E', 'e'],
|
||||
['r', 'R', 'r'],
|
||||
['t', 'T', 't'],
|
||||
['y', 'Y', 'y'],
|
||||
['u', 'U', 'u'],
|
||||
['i', 'I', 'i'],
|
||||
['o', 'O', 'o'],
|
||||
['p', 'P', 'p'],
|
||||
['[', '{', '['],
|
||||
[']', '}', ']'],
|
||||
['\n', '\n', '\n'],
|
||||
['\0', '\0', '\0'],
|
||||
['a', 'A', 'a'],
|
||||
['s', 'S', 's'],
|
||||
['d', 'D', 'd'],
|
||||
['f', 'F', 'f'],
|
||||
['g', 'G', 'g'],
|
||||
['h', 'H', 'h'],
|
||||
['j', 'J', 'j'],
|
||||
['k', 'K', 'k'],
|
||||
['l', 'L', 'l'],
|
||||
[';', ':', ';'],
|
||||
['\'', '"', '\''],
|
||||
['`', '~', '`'],
|
||||
['\0', '\0', '\0'],
|
||||
['\\', '|', '\\'],
|
||||
['z', 'Z', 'z'],
|
||||
['x', 'X', 'x'],
|
||||
['c', 'C', 'c'],
|
||||
['v', 'V', 'v'],
|
||||
['b', 'B', 'b'],
|
||||
['n', 'N', 'n'],
|
||||
['m', 'M', 'm'],
|
||||
[',', '<', ','],
|
||||
['.', '>', '.'],
|
||||
['/', '?', '/'],
|
||||
['\0', '\0', '\0'],
|
||||
['\0', '\0', '\0'],
|
||||
['\0', '\0', '\0'],
|
||||
[' ', ' ', ' ']
|
||||
static ENGLISH: [[char; 2]; 58] = [
|
||||
['\0', '\0'],
|
||||
['\x1B', '\x1B'],
|
||||
['1', '!'],
|
||||
['2', '@'],
|
||||
['3', '#'],
|
||||
['4', '$'],
|
||||
['5', '%'],
|
||||
['6', '^'],
|
||||
['7', '&'],
|
||||
['8', '*'],
|
||||
['9', '('],
|
||||
['0', ')'],
|
||||
['-', '_'],
|
||||
['=', '+'],
|
||||
['\x7F', '\x7F'],
|
||||
['\t', '\t'],
|
||||
['q', 'Q'],
|
||||
['w', 'W'],
|
||||
['e', 'E'],
|
||||
['r', 'R'],
|
||||
['t', 'T'],
|
||||
['y', 'Y'],
|
||||
['u', 'U'],
|
||||
['i', 'I'],
|
||||
['o', 'O'],
|
||||
['p', 'P'],
|
||||
['[', '{'],
|
||||
[']', '}'],
|
||||
['\n', '\n'],
|
||||
['\0', '\0'],
|
||||
['a', 'A'],
|
||||
['s', 'S'],
|
||||
['d', 'D'],
|
||||
['f', 'F'],
|
||||
['g', 'G'],
|
||||
['h', 'H'],
|
||||
['j', 'J'],
|
||||
['k', 'K'],
|
||||
['l', 'L'],
|
||||
[';', ':'],
|
||||
['\'', '"'],
|
||||
['`', '~'],
|
||||
['\0', '\0'],
|
||||
['\\', '|'],
|
||||
['z', 'Z'],
|
||||
['x', 'X'],
|
||||
['c', 'C'],
|
||||
['v', 'V'],
|
||||
['b', 'B'],
|
||||
['n', 'N'],
|
||||
['m', 'M'],
|
||||
[',', '<'],
|
||||
['.', '>'],
|
||||
['/', '?'],
|
||||
['\0', '\0'],
|
||||
['\0', '\0'],
|
||||
['\0', '\0'],
|
||||
[' ', ' ']
|
||||
];
|
||||
|
||||
pub fn get_char(scancode: u8) -> char {
|
||||
pub fn get_char(scancode: u8, shift: bool) -> char {
|
||||
if let Some(c) = ENGLISH.get(scancode as usize) {
|
||||
c[0]
|
||||
if shift {
|
||||
c[1]
|
||||
} else {
|
||||
c[0]
|
||||
}
|
||||
} else {
|
||||
'\0'
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ extern crate ransid;
|
|||
extern crate syscall;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::{slice, thread};
|
||||
|
@ -24,32 +25,55 @@ pub mod primitive;
|
|||
|
||||
struct DisplayScheme {
|
||||
console: RefCell<Console>,
|
||||
display: RefCell<Display>
|
||||
display: RefCell<Display>,
|
||||
input: RefCell<VecDeque<u8>>
|
||||
}
|
||||
|
||||
impl Scheme for DisplayScheme {
|
||||
fn open(&self, _path: &[u8], _flags: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
|
||||
if path == b"input" {
|
||||
Ok(1)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn dup(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn dup(&self, id: usize) -> Result<usize> {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn write(&self, _id: usize, buf: &[u8]) -> Result<usize> {
|
||||
let mut display = self.display.borrow_mut();
|
||||
self.console.borrow_mut().write(buf, |event| {
|
||||
match event {
|
||||
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data),
|
||||
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)
|
||||
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);
|
||||
}
|
||||
});
|
||||
Ok(buf.len())
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
let mut display = self.display.borrow_mut();
|
||||
self.console.borrow_mut().write(buf, |event| {
|
||||
match event {
|
||||
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data),
|
||||
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)
|
||||
}
|
||||
});
|
||||
Ok(buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&self, _id: usize) -> Result<usize> {
|
||||
|
@ -89,15 +113,27 @@ fn main() {
|
|||
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())
|
||||
};
|
||||
|
||||
let mut blocked = VecDeque::new();
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
socket.read(&mut packet).expect("vesad: failed to read display scheme");
|
||||
//println!("vesad: {:?}", packet);
|
||||
scheme.handle(&mut packet);
|
||||
socket.write(&packet).expect("vesad: failed to write display scheme");
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use elf::{self, program_header};
|
|||
use scheme;
|
||||
use syscall;
|
||||
use syscall::error::*;
|
||||
use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE};
|
||||
use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
|
||||
use syscall::validate::{validate_slice, validate_slice_mut};
|
||||
|
||||
pub fn brk(address: usize) -> Result<usize> {
|
||||
|
@ -594,7 +594,7 @@ pub fn sched_yield() -> Result<usize> {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize> {
|
||||
pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
||||
//TODO: Implement status_ptr and options
|
||||
loop {
|
||||
{
|
||||
|
@ -616,6 +616,8 @@ pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize>
|
|||
if exited {
|
||||
let mut contexts = context::contexts_mut();
|
||||
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
|
||||
} else if flags & WNOHANG == WNOHANG {
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
libstd
2
libstd
|
@ -1 +1 @@
|
|||
Subproject commit ae80aff4d39b2d3a83f7d32bc95739e4e1169184
|
||||
Subproject commit a5a6e9fe349d80918d6fc233d23530c4bf3b4f96
|
|
@ -11,13 +11,13 @@ pub fn main() {
|
|||
let sh = args.next().expect("login: no sh provided");
|
||||
let sh_args: Vec<String> = args.collect();
|
||||
|
||||
syscall::close(2);
|
||||
syscall::close(1);
|
||||
syscall::close(0);
|
||||
let _ = syscall::close(2);
|
||||
let _ = syscall::close(1);
|
||||
let _ = syscall::close(0);
|
||||
|
||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
|
|
|
@ -41,3 +41,5 @@ pub const O_FSYNC: usize = 0x80;
|
|||
pub const O_CREAT: usize = 0x200;
|
||||
pub const O_TRUNC: usize = 0x400;
|
||||
pub const O_EXCL: usize = 0x800;
|
||||
|
||||
pub const WNOHANG: usize = 1;
|
||||
|
|
Loading…
Reference in a new issue