1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use arch::keyboard::keys;
use core::char;
use io::{AsyncRead,FlatMap,Read,Write};
use prelude::*;
use process::{KObj,KObjRef};

pub struct Console {
    input: FlatMap,
    output: KObjRef<Write>
}

impl Console {
    pub fn new(input: KObjRef<AsyncRead>, output: KObjRef<Write>) -> Self {
        Console {
            output: output.clone(),
            input: FlatMap::new(input, 4, move |keys| {
                let c = unsafe { *(keys[0..4].as_ptr() as *const u32) };
                let keys = keys::Bucky::from_bits_truncate(c);
                let c = c & !keys.bits();
                if keys.intersects(keys::BUCKY_RELEASE | keys::BUCKY_CTRL | keys::BUCKY_ALT | keys::BUCKY_ALTGR) {
                    Vec::new()
                } else if let Some(c) = char::from_u32(c) {
                    let mut bytes = vec![0; 4];
                    let len = char::encode_utf8(c, &mut bytes).unwrap();
                    bytes.truncate(len);

                    let _ = output.write(&bytes[..]);
                    bytes
                } else {
                    Vec::new()
                }
            }, |left| {
                left.iter().position(|b| *b == 10).map(|index| {
                    let mut right = left.split_off(index);
                    right.remove(0);
                    right
                })
            })
        }
    }
}

impl KObj for Console {
    fn async_read(&self) -> Option<&AsyncRead> {
        Some(&self.input)
    }

    fn read(&self) -> Option<&Read> {
        Some(&self.input)
    }

    fn write(&self) -> Option<&Write> {
        Some(&*self.output)
    }
}