diff --git a/bgad/src/main.rs b/bgad/src/main.rs index eef1377e6e..699c09eb63 100644 --- a/bgad/src/main.rs +++ b/bgad/src/main.rs @@ -3,11 +3,17 @@ extern crate syscall; use std::env; +use std::fs::File; +use std::io::{Read, Write}; use syscall::iopl; +use syscall::data::Packet; +use syscall::scheme::SchemeMut; use bga::Bga; +use scheme::BgaScheme; mod bga; +mod scheme; fn main() { let mut args = env::args().skip(1); @@ -24,7 +30,17 @@ fn main() { if unsafe { syscall::clone(0).unwrap() } == 0 { unsafe { iopl(3).unwrap() }; + let mut socket = File::create(":bga").expect("bgad: failed to create bga scheme"); + let mut bga = Bga::new(); print!("{}", format!(" - BGA {}x{}\n", bga.width(), bga.height())); + + let mut scheme = BgaScheme { bga: bga }; + loop { + let mut packet = Packet::default(); + socket.read(&mut packet).expect("bgad: failed to read events from bga scheme"); + scheme.handle(&mut packet); + socket.write(&packet).expect("bgad: failed to write responses to bga scheme"); + } } } diff --git a/bgad/src/scheme.rs b/bgad/src/scheme.rs new file mode 100644 index 0000000000..d87e1f06b5 --- /dev/null +++ b/bgad/src/scheme.rs @@ -0,0 +1,88 @@ +use std::str; + +use syscall::{Error, Result, SchemeMut, EACCES, EINVAL, MODE_CHR}; +use syscall::data::Stat; + +use bga::Bga; + +pub struct BgaScheme { + pub bga: Bga +} + +impl SchemeMut for BgaScheme { + fn open(&mut self, _path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result { + if uid == 0 { + Ok(0) + } else { + Err(Error::new(EACCES)) + } + } + + fn dup(&mut self, file: usize, buf: &[u8]) -> Result { + if ! buf.is_empty() { + return Err(Error::new(EINVAL)); + } + + Ok(file) + } + + fn read(&mut self, _file: usize, buf: &mut [u8]) -> Result { + let mut i = 0; + let data = format!("{},{}\n", self.bga.width(), self.bga.height()).into_bytes(); + while i < buf.len() && i < data.len() { + buf[i] = data[i]; + i += 1; + } + Ok(i) + } + + fn write(&mut self, _file: usize, buf: &[u8]) -> Result { + let string = str::from_utf8(buf).or(Err(Error::new(EINVAL)))?; + let string = string.trim(); + + let mut parts = string.split(','); + + let width = if let Some(part) = parts.next() { + part.parse::().or(Err(Error::new(EINVAL)))? + } else { + self.bga.width() + }; + + let height = if let Some(part) = parts.next() { + part.parse::().or(Err(Error::new(EINVAL)))? + } else { + self.bga.height() + }; + + self.bga.set_size(width, height); + + Ok(buf.len()) + } + + fn fpath(&mut self, _file: usize, buf: &mut [u8]) -> Result { + let mut i = 0; + let scheme_path = b"bga"; + while i < buf.len() && i < scheme_path.len() { + buf[i] = scheme_path[i]; + i += 1; + } + Ok(i) + } + + fn fstat(&mut self, _id: usize, stat: &mut Stat) -> Result { + *stat = Stat { + st_mode: MODE_CHR | 0o666, + ..Default::default() + }; + + Ok(0) + } + + fn fcntl(&mut self, _id: usize, _cmd: usize, _arg: usize) -> Result { + Ok(0) + } + + fn close(&mut self, _file: usize) -> Result { + Ok(0) + } +}