diff options
Diffstat (limited to 'components/servo/main.rs')
-rw-r--r-- | components/servo/main.rs | 243 |
1 files changed, 138 insertions, 105 deletions
diff --git a/components/servo/main.rs b/components/servo/main.rs index 6acaf013572..1bf329920e3 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -2,116 +2,52 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#![feature(start)] +//! The `servo` test application. +//! +//! Creates a `Browser` instance with a simple implementation of +//! the compositor's `WindowMethods` to create a working web browser. +//! +//! This browser's implementation of `WindowMethods` is built on top +//! of [glutin], the cross-platform OpenGL utility and windowing +//! library. +//! +//! For the engine itself look next door in lib.rs. +//! +//! [glutin]: https://github.com/tomaka/glutin -#[cfg(target_os="android")] -extern crate libc; +#![feature(start)] +// The Servo engine extern crate servo; -extern crate time; -extern crate util; +// Window graphics compositing and message dispatch +extern crate compositing; +// Servo networking extern crate net; - -#[cfg(not(test))] +// Servo common utilitiess +extern crate util; +// The window backed by glutin extern crate "glutin_app" as app; - -#[cfg(not(test))] -extern crate compositing; +extern crate time; #[cfg(target_os="android")] #[macro_use] extern crate android_glue; -#[cfg(target_os="android")] -use libc::c_int; - -#[cfg(not(test))] +use std::rc::Rc; use util::opts; - -#[cfg(not(test))] use net::resource_task; - -#[cfg(not(test))] use servo::Browser; -#[cfg(not(test))] use compositing::windowing::WindowEvent; #[cfg(target_os="android")] use std::borrow::ToOwned; -#[cfg(not(test))] -struct BrowserWrapper { - browser: Browser, -} - -#[cfg(target_os="android")] -android_start!(main); - -#[cfg(target_os="android")] -fn get_args() -> Vec<String> { - vec![ - "servo".to_owned(), - "http://en.wikipedia.org/wiki/Rust".to_owned() - ] -} - -#[cfg(not(target_os="android"))] -fn get_args() -> Vec<String> { - use std::env; - env::args().collect() -} - -#[cfg(target_os="android")] -struct FilePtr(*mut libc::types::common::c95::FILE); - -#[cfg(target_os="android")] -unsafe impl Send for FilePtr {} - -#[cfg(target_os="android")] -fn redirect_output(file_no: c_int) { - use libc::funcs::posix88::unistd::{pipe, dup2}; - use libc::funcs::posix88::stdio::fdopen; - use libc::funcs::c95::stdio::fgets; - use util::task::spawn_named; - use std::mem; - use std::ffi::CString; - use std::str::from_utf8; - - unsafe { - let mut pipes: [c_int; 2] = [ 0, 0 ]; - pipe(pipes.as_mut_ptr()); - dup2(pipes[1], file_no); - let mode = CString::new("r").unwrap(); - let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr())); - spawn_named("android-logger".to_owned(), move || { - loop { - let mut read_buffer: [u8; 1024] = mem::zeroed(); - let FilePtr(input_file) = input_file; - fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file); - match from_utf8(&read_buffer) { - Ok(s) => android_glue::write_log(s.trim_right_matches('\0')), - _ => {} - } - } - }); - } -} - -#[cfg(target_os="android")] -fn setup_logging() { - use libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO}; - //os::setenv("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra"); - redirect_output(STDERR_FILENO); - redirect_output(STDOUT_FILENO); -} - -#[cfg(not(target_os="android"))] -fn setup_logging() { -} - fn main() { + // Parse the command line options and store them globally if opts::from_cmdline_args(&*get_args()) { setup_logging(); + + // Possibly interpret the `HOST_FILE` environment variable resource_task::global_init(); let window = if opts::get().headless { @@ -120,21 +56,18 @@ fn main() { Some(app::create_window()) }; + // Our wrapper around `Browser` that also implements some + // callbacks required by the glutin window implementation. let mut browser = BrowserWrapper { browser: Browser::new(window.clone()), }; - match window { - None => {} - Some(ref window) => { - unsafe { - window.set_nested_event_loop_listener(&mut browser); - } - } - } + maybe_register_glutin_resize_handler(&window, &mut browser); browser.browser.handle_event(WindowEvent::InitializeCompositing); + // Feed events from the window to the browser until the browser + // says to stop. loop { let should_continue = match window { None => browser.browser.handle_event(WindowEvent::Idle), @@ -148,14 +81,7 @@ fn main() { } }; - match window { - None => {} - Some(ref window) => { - unsafe { - window.remove_nested_event_loop_listener(); - } - } - } + maybe_unregister_glutin_resize_handler(&window); let BrowserWrapper { browser @@ -164,6 +90,33 @@ fn main() { } } +fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>, + browser: &mut BrowserWrapper) { + match *window { + None => {} + Some(ref window) => { + unsafe { + window.set_nested_event_loop_listener(browser); + } + } + } +} + +fn maybe_unregister_glutin_resize_handler(window: &Option<Rc<app::window::Window>>) { + match *window { + None => {} + Some(ref window) => { + unsafe { + window.remove_nested_event_loop_listener(); + } + } + } +} + +struct BrowserWrapper { + browser: Browser, +} + impl app::NestedEventLoopListener for BrowserWrapper { fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool { let is_resize = match event { @@ -180,3 +133,83 @@ impl app::NestedEventLoopListener for BrowserWrapper { } } +#[cfg(target_os="android")] +fn setup_logging() { + android::setup_logging(); +} + +#[cfg(not(target_os="android"))] +fn setup_logging() { +} + +#[cfg(target_os="android")] +fn get_args() -> Vec<String> { + vec![ + "servo".to_owned(), + "http://en.wikipedia.org/wiki/Rust".to_owned() + ] +} + +#[cfg(not(target_os="android"))] +fn get_args() -> Vec<String> { + use std::env; + env::args().collect() +} + +// This macro must be used at toplevel because it defines a nested +// module, but macros can only accept identifiers - not paths - +// preventing the expansion of this macro within the android module +// without use of an additionl stub method or other hackery. +#[cfg(target_os = "android")] +android_start!(main); + +#[cfg(target_os = "android")] +mod android { + extern crate libc; + extern crate android_glue; + + use self::libc::c_int; + use std::borrow::ToOwned; + + pub fn setup_logging() { + use self::libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO}; + //os::setenv("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra"); + redirect_output(STDERR_FILENO); + redirect_output(STDOUT_FILENO); + } + + struct FilePtr(*mut self::libc::types::common::c95::FILE); + + unsafe impl Send for FilePtr {} + + fn redirect_output(file_no: c_int) { + use self::libc::funcs::posix88::unistd::{pipe, dup2}; + use self::libc::funcs::posix88::stdio::fdopen; + use self::libc::funcs::c95::stdio::fgets; + use util::task::spawn_named; + use std::mem; + use std::ffi::CString; + use std::str::from_utf8; + + unsafe { + let mut pipes: [c_int; 2] = [ 0, 0 ]; + pipe(pipes.as_mut_ptr()); + dup2(pipes[1], file_no); + let mode = CString::from_slice("r".as_bytes()); + let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr())); + spawn_named("android-logger".to_owned(), move || { + loop { + let mut read_buffer: [u8; 1024] = mem::zeroed(); + let FilePtr(input_file) = input_file; + fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file); + let cs = CString::from_slice(&read_buffer); + match from_utf8(cs.as_bytes()) { + Ok(s) => android_glue::write_log(s), + _ => {} + } + } + }); + } + } + +} |