aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/servo/content.rs22
-rw-r--r--src/servo/dom/event.rs4
-rw-r--r--src/servo/engine.rs85
-rw-r--r--src/servo/gfx/pngsink.rs4
-rw-r--r--src/servo/gfx/renderer.rs4
-rw-r--r--src/servo/platform/osmain.rs17
-rwxr-xr-xsrc/servo/servo.rc1
-rw-r--r--src/servo/servo.rs10
8 files changed, 102 insertions, 45 deletions
diff --git a/src/servo/content.rs b/src/servo/content.rs
index 99a4bdc70cd..9a0a0364193 100644
--- a/src/servo/content.rs
+++ b/src/servo/content.rs
@@ -7,14 +7,16 @@ export Content;
export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg;
export PingMsg, PongMsg;
-import comm::{port, chan, listen};
+import comm::{port, chan, listen, select2};
import task::{spawn, spawn_listener};
import io::{read_whole_file, println};
import result::{ok, err};
import dom::base::NodeScope;
+import dom::event::ResizeEvent;
import dom::rcu::WriterMethods;
import dom::style;
+import gfx::renderer::Sink;
import parser::html_lexer::spawn_html_lexer_task;
import parser::css_builder::build_stylesheet;
import parser::html_builder::build_dom;
@@ -25,6 +27,7 @@ import jsrt = js::rust::rt;
import js::rust::methods;
import js::global::{global_class, debug_fns};
+import either::{left, right};
import result::extensions;
type Content = chan<ControlMsg>;
@@ -53,13 +56,16 @@ fn join_layout(scope: NodeScope, layout: Layout) {
}
#[warn(no_non_implicitly_copyable_typarams)]
-fn Content(layout: Layout) -> Content {
+fn Content<S:Sink send copy>(layout: Layout, sink: S) -> Content {
spawn_listener::<ControlMsg>(|from_master| {
+ let event_port = port();
+ sink.add_event_listener(event_port.chan());
+
let scope = NodeScope();
let rt = jsrt();
loop {
- alt from_master.recv() {
- ParseMsg(filename) {
+ alt select2(from_master, event_port) {
+ left(ParseMsg(filename)) {
#debug["content: Received filename `%s` to parse", *filename];
// Note: we can parse the next document in parallel
@@ -85,7 +91,7 @@ fn Content(layout: Layout) -> Content {
scope.reader_forked();
}
- ExecuteMsg(filename) {
+ left(ExecuteMsg(filename)) {
#debug["content: Received filename `%s` to execute", *filename];
alt read_whole_file(*filename) {
@@ -104,10 +110,14 @@ fn Content(layout: Layout) -> Content {
}
}
- ExitMsg {
+ left(ExitMsg) {
layout.send(layout_task::ExitMsg);
break;
}
+
+ right(ResizeEvent(new_width, new_height)) {
+ #debug("content got resize event: %d, %d", new_width, new_height);
+ }
}
}
})
diff --git a/src/servo/dom/event.rs b/src/servo/dom/event.rs
new file mode 100644
index 00000000000..2b9dcabe038
--- /dev/null
+++ b/src/servo/dom/event.rs
@@ -0,0 +1,4 @@
+enum Event {
+ ResizeEvent(int, int)
+}
+
diff --git a/src/servo/engine.rs b/src/servo/engine.rs
index 92ae708a2d6..ca5f9b2a5f3 100644
--- a/src/servo/engine.rs
+++ b/src/servo/engine.rs
@@ -5,46 +5,61 @@ import layout::layout_task;
import layout_task::Layout;
import content::{Content, ExecuteMsg, ParseMsg, ExitMsg};
-type Engine = chan<Msg>;
+class Engine<S:Sink send copy> {
+ let sink: S;
-enum Msg {
- LoadURLMsg(~str),
- ExitMsg(chan<()>)
-}
+ let renderer: Renderer;
+ let layout: Layout;
+ let content: Content;
-fn Engine<S: Sink send copy>(sink: S) -> Engine {
- spawn_listener::<Msg>(|request| {
- // The renderer
- let renderer = Renderer(sink);
+ new(sink: S) {
+ self.sink = sink;
- // The layout task
+ let renderer = Renderer(sink);
let layout = Layout(renderer);
+ let content = Content(layout, sink);
+
+ self.renderer = renderer;
+ self.layout = layout;
+ self.content = content;
+ }
+
+ fn start() -> chan<Msg> {
+ do spawn_listener::<Msg> |request| {
+ while self.handle_request(request.recv()) {
+ // Go on...
+ }
+ }
+ }
+
+ fn handle_request(request: Msg) -> bool {
+ alt request {
+ LoadURLMsg(url) {
+ let url = copy url;
+ if (*url).ends_with(".js") {
+ self.content.send(ExecuteMsg(url))
+ } else {
+ self.content.send(ParseMsg(url))
+ }
+ ret true;
+ }
- // The content task
- let content = Content(layout);
-
- loop {
- alt request.recv() {
- LoadURLMsg(url) {
- let url = copy url;
- if (*url).ends_with(".js") {
- content.send(ExecuteMsg(url))
- } else {
- content.send(ParseMsg(url))
- }
- }
-
- ExitMsg(sender) {
- content.send(content::ExitMsg);
- layout.send(layout_task::ExitMsg);
- listen(|response_channel| {
- renderer.send(renderer::ExitMsg(response_channel));
- response_channel.recv();
- });
- sender.send(());
- break;
- }
+ ExitMsg(sender) {
+ self.content.send(content::ExitMsg);
+ self.layout.send(layout_task::ExitMsg);
+ do listen |response_channel| {
+ self.renderer.send(renderer::ExitMsg(response_channel));
+ response_channel.recv();
}
+ sender.send(());
+ ret false;
+ }
}
- })
+ }
}
+
+enum Msg {
+ LoadURLMsg(~str),
+ ExitMsg(chan<()>)
+}
+
diff --git a/src/servo/gfx/pngsink.rs b/src/servo/gfx/pngsink.rs
index 3e51e57ccee..ec1e18d351c 100644
--- a/src/servo/gfx/pngsink.rs
+++ b/src/servo/gfx/pngsink.rs
@@ -23,6 +23,7 @@ import comm::chan;
import unsafe::reinterpret_cast;
import vec_from_buf = vec::unsafe::from_buf;
import ptr::addr_of;
+import dom::event::Event;
type PngSink = chan<Msg>;
@@ -39,6 +40,9 @@ impl PngSink of Sink for chan<Msg> {
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(Draw(next_dt, draw_me))
}
+ fn add_event_listener(_listener: chan<Event>) {
+ // No events in this sink.
+ }
}
fn PngSink(output: chan<[u8]>) -> PngSink {
diff --git a/src/servo/gfx/renderer.rs b/src/servo/gfx/renderer.rs
index cf0c18cbdd4..7987d1a299c 100644
--- a/src/servo/gfx/renderer.rs
+++ b/src/servo/gfx/renderer.rs
@@ -7,6 +7,7 @@ import azure::*;
import azure::bindgen::*;
import libc::size_t;
import text::text_run::TextRun;
+import dom::event::{Event, ResizeEvent};
type Renderer = chan<Msg>;
@@ -18,10 +19,13 @@ enum Msg {
#[doc = "
The interface used to by the renderer to aquire draw targets for
each rendered frame and submit them to be drawn to the display
+
+FIXME: Change this name to Compositor.
"]
iface Sink {
fn begin_drawing(next_dt: chan<AzDrawTargetRef>);
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef);
+ fn add_event_listener(listener: chan<Event>);
}
fn Renderer<S: Sink send copy>(sink: S) -> chan<Msg> {
diff --git a/src/servo/platform/osmain.rs b/src/servo/platform/osmain.rs
index f6200316cdf..70b15d3f622 100644
--- a/src/servo/platform/osmain.rs
+++ b/src/servo/platform/osmain.rs
@@ -6,8 +6,10 @@ import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
+import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};
+import dom::event::{Event, ResizeEvent};
import layers::ImageLayer;
import geom::size::Size2D;
import std::cmp::fuzzy_eq;
@@ -18,6 +20,7 @@ enum Msg {
BeginDrawing(chan<AzDrawTargetRef>),
Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
AddKeyHandler(chan<()>),
+ AddEventListener(chan<Event>),
Exit
}
@@ -32,6 +35,7 @@ fn OSMain() -> OSMain {
fn mainloop(po: port<Msg>) {
let mut key_handlers: [chan<()>] = [];
+ let event_listeners: @dvec<chan<Event>> = @dvec();
glut::init();
glut::init_display_mode(glut::DOUBLE);
@@ -51,6 +55,13 @@ fn mainloop(po: port<Msg>) {
let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
Size2D(800.0f32, 600.0f32));
+ do glut::reshape_func(window) |width, height| {
+ #debug("osmain: window resized to %d,%d", width as int, height as int);
+ for event_listeners.each |event_listener| {
+ event_listener.send(ResizeEvent(width as int, height as int));
+ }
+ }
+
loop {
do glut::display_func() {
#debug("osmain: drawing to screen");
@@ -66,6 +77,9 @@ fn mainloop(po: port<Msg>) {
AddKeyHandler(key_ch) {
key_handlers += [key_ch];
}
+ AddEventListener(event_listener) {
+ event_listeners.push(event_listener);
+ }
BeginDrawing(sender) {
lend_surface(surfaces, sender);
}
@@ -107,6 +121,9 @@ impl OSMain of Sink for OSMain {
fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
self.send(Draw(next_dt, draw_me))
}
+ fn add_event_listener(listener: chan<Event>) {
+ self.send(AddEventListener(listener));
+ }
}
type surface_set = {
diff --git a/src/servo/servo.rc b/src/servo/servo.rc
index 2674da547a5..e2be7c2b17d 100755
--- a/src/servo/servo.rc
+++ b/src/servo/servo.rc
@@ -20,6 +20,7 @@ use layers;
mod dom {
mod base;
+ mod event;
mod rcu;
mod style;
}
diff --git a/src/servo/servo.rs b/src/servo/servo.rs
index 651ad7de3ce..fce2e92251d 100644
--- a/src/servo/servo.rs
+++ b/src/servo/servo.rs
@@ -32,6 +32,7 @@ fn run_pipeline_screen(urls: [str]) {
// Create a serve instance
let engine = Engine(osmain);
+ let engine_chan = engine.start();
// Send each file to render then wait for keypress
listen(|keypress_from_osmain| {
@@ -39,7 +40,7 @@ fn run_pipeline_screen(urls: [str]) {
for urls.each |filename| {
#debug["master: Sending filename `%s`", filename];
- engine.send(LoadURLMsg(~copy filename));
+ engine_chan.send(LoadURLMsg(~copy filename));
#debug["master: Waiting for keypress"];
keypress_from_osmain.recv();
}
@@ -48,7 +49,7 @@ fn run_pipeline_screen(urls: [str]) {
// Shut everything down
#debug["master: Shut down"];
listen(|exit_response_from_engine| {
- engine.send(engine::ExitMsg(exit_response_from_engine));
+ engine_chan.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv();
});
osmain.send(osmain::Exit);
@@ -65,8 +66,9 @@ fn run_pipeline_png(-url: str, outfile: str) {
listen(|pngdata_from_sink| {
let sink = PngSink(pngdata_from_sink);
let engine = Engine(sink);
+ let engine_chan = engine.start();
let url = copy url;
- engine.send(LoadURLMsg(~url));
+ engine_chan.send(LoadURLMsg(~url));
alt buffered_file_writer(outfile) {
ok(writer) {
writer.write(pngdata_from_sink.recv())
@@ -74,7 +76,7 @@ fn run_pipeline_png(-url: str, outfile: str) {
err(e) { fail e }
}
listen(|exit_response_from_engine| {
- engine.send(engine::ExitMsg(exit_response_from_engine));
+ engine_chan.send(engine::ExitMsg(exit_response_from_engine));
exit_response_from_engine.recv();
});
sink.send(pngsink::Exit);