scheme.rs 5.41 KB
Newer Older
Jeremy Soller's avatar
Jeremy Soller committed
1
use std::collections::BTreeMap;
Jeremy Soller's avatar
Jeremy Soller committed
2
use std::{mem, slice, str};
Jeremy Soller's avatar
Jeremy Soller committed
3

Jeremy Soller's avatar
Jeremy Soller committed
4
use orbclient::{Event, EventOption};
5
use syscall::{Result, Error, EACCES, EBADF, ENOENT, SchemeMut};
Jeremy Soller's avatar
Jeremy Soller committed
6 7

use display::Display;
Jeremy Soller's avatar
Jeremy Soller committed
8
use screen::{Screen, GraphicScreen, TextScreen};
Jeremy Soller's avatar
Jeremy Soller committed
9 10

pub struct DisplayScheme {
11 12
    active: usize,
    pub screens: BTreeMap<usize, Box<Screen>>
Jeremy Soller's avatar
Jeremy Soller committed
13 14 15
}

impl DisplayScheme {
Jeremy Soller's avatar
Jeremy Soller committed
16
    pub fn new(width: usize, height: usize, onscreen: usize, spec: &[bool]) -> DisplayScheme {
Jeremy Soller's avatar
Jeremy Soller committed
17
        let mut screens: BTreeMap<usize, Box<Screen>> = BTreeMap::new();
Jeremy Soller's avatar
Jeremy Soller committed
18 19 20 21 22 23 24 25 26 27

        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;
        }
Jeremy Soller's avatar
Jeremy Soller committed
28 29

        DisplayScheme {
30 31
            active: 1,
            screens: screens
Jeremy Soller's avatar
Jeremy Soller committed
32 33 34 35
        }
    }

    pub fn will_block(&self, id: usize) -> bool {
36
        if let Some(screen) = self.screens.get(&id) {
Jeremy Soller's avatar
Jeremy Soller committed
37 38 39 40 41 42 43
            screen.will_block()
        } else {
            false
        }
    }
}

44 45
impl SchemeMut for DisplayScheme {
    fn open(&mut self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
Jeremy Soller's avatar
Jeremy Soller committed
46
        if path == b"input" {
Jeremy Soller's avatar
Jeremy Soller committed
47 48 49 50 51
            if uid == 0 {
                Ok(0)
            } else {
                Err(Error::new(EACCES))
            }
Jeremy Soller's avatar
Jeremy Soller committed
52 53 54
        } else {
            let path_str = str::from_utf8(path).unwrap_or("");
            let id = path_str.parse::<usize>().unwrap_or(0);
55
            if self.screens.contains_key(&id) {
Jeremy Soller's avatar
Jeremy Soller committed
56 57 58 59 60 61 62
                Ok(id)
            } else {
                Err(Error::new(ENOENT))
            }
        }
    }

Jeremy Soller's avatar
Jeremy Soller committed
63
    fn dup(&mut self, id: usize, _buf: &[u8]) -> Result<usize> {
Jeremy Soller's avatar
Jeremy Soller committed
64 65 66
        Ok(id)
    }

67 68
    fn fevent(&mut self, id: usize, flags: usize) -> Result<usize> {
        if let Some(mut screen) = self.screens.get_mut(&id) {
69
            screen.event(flags).and(Ok(id))
Jeremy Soller's avatar
Jeremy Soller committed
70 71 72 73 74
        } else {
            Err(Error::new(EBADF))
        }
    }

75
    fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
Jeremy Soller's avatar
Jeremy Soller committed
76 77
        let path_str = if id == 0 {
            format!("display:input")
78
        } else if let Some(screen) = self.screens.get(&id) {
Jeremy Soller's avatar
Jeremy Soller committed
79
            format!("display:{}/{}/{}", id, screen.width(), screen.height())
Jeremy Soller's avatar
Jeremy Soller committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
        } 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)
    }

95 96 97
    fn fsync(&mut self, id: usize) -> Result<usize> {
        if let Some(mut screen) = self.screens.get_mut(&id) {
            if id == self.active {
Jeremy Soller's avatar
Jeremy Soller committed
98 99 100 101 102 103 104 105
                screen.sync();
            }
            Ok(0)
        } else {
            Err(Error::new(EBADF))
        }
    }

106 107
    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        if let Some(mut screen) = self.screens.get_mut(&id) {
Jeremy Soller's avatar
Jeremy Soller committed
108 109 110 111 112 113
            screen.read(buf)
        } else {
            Err(Error::new(EBADF))
        }
    }

114
    fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
Jeremy Soller's avatar
Jeremy Soller committed
115 116 117
        if id == 0 {
            if buf.len() == 1 && buf[0] >= 0xF4 {
                let new_active = (buf[0] - 0xF4) as usize + 1;
118 119
                if let Some(mut screen) = self.screens.get_mut(&new_active) {
                    self.active = new_active;
Jeremy Soller's avatar
Jeremy Soller committed
120 121 122 123
                    screen.redraw();
                }
                Ok(1)
            } else {
Jeremy Soller's avatar
Jeremy Soller committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
                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 {
145 146
                        if let Some(mut screen) = self.screens.get_mut(&new_active) {
                            self.active = new_active;
Jeremy Soller's avatar
Jeremy Soller committed
147 148 149
                            screen.redraw();
                        }
                    } else {
150
                        if let Some(mut screen) = self.screens.get_mut(&self.active) {
Jeremy Soller's avatar
Jeremy Soller committed
151 152 153
                            screen.input(event);
                        }
                    }
Jeremy Soller's avatar
Jeremy Soller committed
154
                }
Jeremy Soller's avatar
Jeremy Soller committed
155 156

                Ok(events.len() * mem::size_of::<Event>())
Jeremy Soller's avatar
Jeremy Soller committed
157
            }
158 159
        } else if let Some(mut screen) = self.screens.get_mut(&id) {
            screen.write(buf, id == self.active)
Jeremy Soller's avatar
Jeremy Soller committed
160 161 162 163 164
        } else {
            Err(Error::new(EBADF))
        }
    }

165 166
    fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
        if let Some(mut screen) = self.screens.get_mut(&id) {
Jeremy Soller's avatar
Jeremy Soller committed
167 168 169 170 171 172
            screen.seek(pos, whence)
        } else {
            Err(Error::new(EBADF))
        }
    }

173
    fn close(&mut self, _id: usize) -> Result<usize> {
Jeremy Soller's avatar
Jeremy Soller committed
174 175 176
        Ok(0)
    }
}