main.rs 3.68 KB
Newer Older
1
#![deny(warnings)]
2 3 4 5 6
#![feature(alloc)]
#![feature(asm)]
#![feature(heap_api)]

extern crate alloc;
Jeremy Soller's avatar
Jeremy Soller committed
7
extern crate orbclient;
8 9
extern crate syscall;

10
use std::env;
11
use std::fs::File;
Jeremy Soller's avatar
Jeremy Soller committed
12
use std::io::{Read, Write};
13
use syscall::{physmap, physunmap, Packet, SchemeMut, EVENT_READ, MAP_WRITE, MAP_WRITE_COMBINE};
14 15

use mode_info::VBEModeInfo;
16
use primitive::fast_set64;
Jeremy Soller's avatar
Jeremy Soller committed
17
use scheme::DisplayScheme;
18 19 20 21

pub mod display;
pub mod mode_info;
pub mod primitive;
Jeremy Soller's avatar
Jeremy Soller committed
22 23
pub mod scheme;
pub mod screen;
Jeremy Soller's avatar
Jeremy Soller committed
24

25
fn main() {
Jeremy Soller's avatar
Jeremy Soller committed
26 27 28 29 30 31 32 33 34 35 36 37
    let mut spec = Vec::new();

    for arg in env::args().skip(1) {
        if arg == "T" {
            spec.push(false);
        } else if arg == "G" {
            spec.push(true);
        } else {
            println!("vesad: unknown screen type: {}", arg);
        }
    }

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    let width;
    let height;
    let physbaseptr;

    {
        let mode_info = unsafe { &*(physmap(0x5200, 4096, 0).expect("vesad: failed to map VBE info") as *const VBEModeInfo) };

        width = mode_info.xresolution as usize;
        height = mode_info.yresolution as usize;
        physbaseptr = mode_info.physbaseptr as usize;

        unsafe { let _ = physunmap(mode_info as *const _ as usize); }
    }

    if physbaseptr > 0 {
53 54
        // Daemonize
        if unsafe { syscall::clone(0).unwrap() } == 0 {
Jeremy Soller's avatar
Jeremy Soller committed
55
            let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
Jeremy Soller's avatar
Jeremy Soller committed
56

57
            let size = width * height;
Jeremy Soller's avatar
Jeremy Soller committed
58 59 60
            //TODO: Remap on resize
            let largest_size = 8 * 1024 * 1024;
            let onscreen = unsafe { physmap(physbaseptr, largest_size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
61 62
            unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };

63
            let mut scheme = DisplayScheme::new(width, height, onscreen, &spec);
64

Jeremy Soller's avatar
Jeremy Soller committed
65
            let mut blocked = Vec::new();
Jeremy Soller's avatar
Jeremy Soller committed
66 67
            loop {
                let mut packet = Packet::default();
68
                socket.read(&mut packet).expect("vesad: failed to read display scheme");
69 70

                // If it is a read packet, and there is no data, block it. Otherwise, handle packet
71
                if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.can_read(packet.b).is_none() {
Jeremy Soller's avatar
Jeremy Soller committed
72
                    blocked.push(packet);
73 74 75 76
                } else {
                    scheme.handle(&mut packet);
                    socket.write(&packet).expect("vesad: failed to write display scheme");
                }
77 78

                // If there are blocked readers, and data is available, handle them
Jeremy Soller's avatar
Jeremy Soller committed
79 80 81
                {
                    let mut i = 0;
                    while i < blocked.len() {
82
                        if scheme.can_read(blocked[i].b).is_some() {
Jeremy Soller's avatar
Jeremy Soller committed
83 84 85 86 87 88
                            let mut packet = blocked.remove(i);
                            scheme.handle(&mut packet);
                            socket.write(&packet).expect("vesad: failed to write display scheme");
                        } else {
                            i += 1;
                        }
89 90
                    }
                }
91

92
                for (screen_id, screen) in scheme.screens.iter() {
93
                    if let Some(count) = screen.can_read() {
94 95 96 97 98 99 100 101
                        let event_packet = Packet {
                            id: 0,
                            pid: 0,
                            uid: 0,
                            gid: 0,
                            a: syscall::number::SYS_FEVENT,
                            b: *screen_id,
                            c: EVENT_READ,
102
                            d: count
103 104 105 106
                        };

                        socket.write(&event_packet).expect("vesad: failed to write display event");
                    }
107
                }
Jeremy Soller's avatar
Jeremy Soller committed
108
            }
109
        }
110 111
    }
}