mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Remove the glfw port (it doesn't compile since last rustup anyway).
This commit is contained in:
parent
ccdf0bd65e
commit
f495884dcb
12 changed files with 10 additions and 744 deletions
|
@ -1,18 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
//! Platform-specific functionality for Servo.
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
pub use platform::common::glut_windowing::{Application, Window};
|
||||
#[cfg(not(target_os="android"))]
|
||||
pub use platform::common::glfw_windowing::{Application, Window};
|
||||
|
||||
pub mod common {
|
||||
#[cfg(target_os="android")]
|
||||
pub mod glut_windowing;
|
||||
#[cfg(not(target_os="android"))]
|
||||
pub mod glfw_windowing;
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ pub enum KeyState {
|
|||
Repeated,
|
||||
}
|
||||
|
||||
//N.B. Straight up copied from glfw-rs
|
||||
//N.B. Based on the glutin key enum
|
||||
#[derive(Show, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Key {
|
||||
Space,
|
||||
|
|
36
components/servo/Cargo.lock
generated
36
components/servo/Cargo.lock
generated
|
@ -6,7 +6,6 @@ dependencies = [
|
|||
"compositing 0.0.1",
|
||||
"devtools 0.0.1",
|
||||
"gfx 0.0.1",
|
||||
"glfw_app 0.0.1",
|
||||
"glutin_app 0.0.1",
|
||||
"layout 0.0.1",
|
||||
"msg 0.0.1",
|
||||
|
@ -332,36 +331,6 @@ dependencies = [
|
|||
"gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glfw"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/servo/glfw-rs?branch=servo#907db700166b48e71d7d59b1eb9964b874c7ca42"
|
||||
dependencies = [
|
||||
"glfw-sys 3.0.4 (git+https://github.com/servo/glfw?branch=cargo-3.0.4)",
|
||||
"log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glfw-sys"
|
||||
version = "3.0.4"
|
||||
source = "git+https://github.com/servo/glfw?branch=cargo-3.0.4#765dace7e4125b87c764f5ac0e7a80eae5c550b2"
|
||||
|
||||
[[package]]
|
||||
name = "glfw_app"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"cgl 0.0.1 (git+https://github.com/servo/rust-cgl)",
|
||||
"compositing 0.0.1",
|
||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
|
||||
"glfw 0.0.1 (git+https://github.com/servo/glfw-rs?branch=servo)",
|
||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||
"msg 0.0.1",
|
||||
"time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glutin"
|
||||
version = "0.0.4-pre"
|
||||
|
@ -711,11 +680,6 @@ dependencies = [
|
|||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "skia-sys"
|
||||
version = "0.0.20130412"
|
||||
|
|
|
@ -30,8 +30,7 @@ path = "../../tests/contenttest.rs"
|
|||
harness = false
|
||||
|
||||
[features]
|
||||
default = ["glutin_app", "window"]
|
||||
glfw = ["glfw_app"]
|
||||
default = ["window"]
|
||||
window = ["glutin_app/window"]
|
||||
headless = ["glutin_app/headless"]
|
||||
|
||||
|
@ -59,13 +58,8 @@ path = "../gfx"
|
|||
[dependencies.devtools]
|
||||
path = "../devtools"
|
||||
|
||||
[dependencies.glfw_app]
|
||||
path = "../../ports/glfw"
|
||||
optional = true
|
||||
|
||||
[dependencies.glutin_app]
|
||||
path = "../../ports/glutin"
|
||||
optional = true
|
||||
|
||||
[dependencies.android_glue]
|
||||
path = "../../support/android-rs-glue/glue"
|
||||
|
|
|
@ -13,10 +13,8 @@ extern crate servo;
|
|||
extern crate time;
|
||||
extern crate util;
|
||||
|
||||
#[cfg(all(feature = "glutin_app",not(test)))]
|
||||
#[cfg(not(test))]
|
||||
extern crate "glutin_app" as app;
|
||||
#[cfg(all(feature = "glfw",not(test)))]
|
||||
extern crate "glfw_app" as app;
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern crate compositing;
|
||||
|
|
6
ports/cef/Cargo.lock
generated
6
ports/cef/Cargo.lock
generated
|
@ -333,7 +333,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glutin"
|
||||
version = "0.0.4-pre"
|
||||
source = "git+https://github.com/tomaka/glutin#1d6b863cd454839b8e3cf1e296cbf8f31fb70029"
|
||||
source = "git+https://github.com/servo/glutin?branch=servo#3814e0cadc85f558b7a417c9d4b97337382aeb36"
|
||||
dependencies = [
|
||||
"android_glue 0.0.1 (git+https://github.com/tomaka/android-rs-glue)",
|
||||
"cocoa 0.1.1 (git+https://github.com/servo/rust-cocoa)",
|
||||
|
@ -354,7 +354,7 @@ dependencies = [
|
|||
"egl 0.1.0 (git+https://github.com/servo/rust-egl)",
|
||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||
"gleam 0.0.1 (git+https://github.com/servo/gleam)",
|
||||
"glutin 0.0.4-pre (git+https://github.com/tomaka/glutin)",
|
||||
"glutin 0.0.4-pre (git+https://github.com/servo/glutin?branch=servo)",
|
||||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||
"msg 0.0.1",
|
||||
"time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -575,7 +575,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! Off-screen windows.
|
||||
//!
|
||||
//! This is used for off-screen rendering mode only; on-screen windows (the default embedding mode)
|
||||
//! are managed by a platform toolkit (GLFW or Glutin).
|
||||
//! are managed by a platform toolkit (Glutin).
|
||||
|
||||
use eutil::Downcast;
|
||||
use interfaces::CefBrowser;
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
[package]
|
||||
name = "glfw_app"
|
||||
version = "0.0.1"
|
||||
authors = ["The Servo Project Developers"]
|
||||
|
||||
[lib]
|
||||
name = "glfw_app"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.compositing]
|
||||
path = "../../components/compositing"
|
||||
|
||||
[dependencies.geom]
|
||||
git = "https://github.com/servo/rust-geom"
|
||||
|
||||
[dependencies.glfw]
|
||||
git = "https://github.com/servo/glfw-rs"
|
||||
branch = "servo"
|
||||
|
||||
[dependencies.layers]
|
||||
git = "https://github.com/servo/rust-layers"
|
||||
|
||||
[dependencies.msg]
|
||||
path = "../../components/msg"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../../components/util"
|
||||
|
||||
[dependencies.cgl]
|
||||
git = "https://github.com/servo/rust-cgl"
|
||||
|
||||
[dependencies.gleam]
|
||||
git = "https://github.com/servo/gleam"
|
||||
|
||||
[dependencies]
|
||||
time = "0.1.12"
|
|
@ -1,50 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
//! A simple application that uses GLFW to open a window for Servo to display in.
|
||||
|
||||
#![feature(macro_rules)]
|
||||
#![deny(unused_imports, unused_variables)]
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
extern crate cgl;
|
||||
extern crate compositing;
|
||||
extern crate geom;
|
||||
extern crate gleam;
|
||||
extern crate glfw;
|
||||
extern crate layers;
|
||||
extern crate libc;
|
||||
extern crate msg;
|
||||
extern crate time;
|
||||
extern crate util;
|
||||
|
||||
use compositing::windowing::WindowEvent;
|
||||
use geom::scale_factor::ScaleFactor;
|
||||
use std::rc::Rc;
|
||||
use window::Window;
|
||||
use util::opts;
|
||||
|
||||
pub mod window;
|
||||
|
||||
pub trait NestedEventLoopListener {
|
||||
fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool;
|
||||
}
|
||||
|
||||
pub fn create_window() -> Rc<Window> {
|
||||
// Initialize GLFW.
|
||||
let glfw = glfw::init(glfw::LOG_ERRORS).unwrap_or_else(|_| {
|
||||
// handles things like inability to connect to X
|
||||
// cannot simply fail, since the runtime isn't up yet (causes a nasty abort)
|
||||
println!("GLFW initialization failed");
|
||||
unsafe { libc::exit(1); }
|
||||
});
|
||||
|
||||
// Read command-line options.
|
||||
let foreground = opts::get().output_file.is_none();
|
||||
let scale_factor = opts::get().device_pixels_per_px.unwrap_or(ScaleFactor(1.0));
|
||||
let size = opts::get().initial_window_size.as_f32() * scale_factor;
|
||||
|
||||
// Open a window.
|
||||
Window::new(glfw, foreground, size.as_uint())
|
||||
}
|
|
@ -1,586 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
//! A windowing implementation using GLFW.
|
||||
|
||||
use NestedEventLoopListener;
|
||||
|
||||
use compositing::compositor_task::{self, CompositorProxy, CompositorReceiver};
|
||||
use compositing::windowing::WindowNavigateMsg;
|
||||
use compositing::windowing::{MouseWindowEvent, WindowEvent, WindowMethods};
|
||||
use geom::point::{Point2D, TypedPoint2D};
|
||||
use geom::scale_factor::ScaleFactor;
|
||||
use geom::size::TypedSize2D;
|
||||
use glfw::{self, Context};
|
||||
use gleam::gl;
|
||||
use layers::geometry::DevicePixel;
|
||||
use layers::platform::surface::NativeGraphicsMetadata;
|
||||
use libc::c_int;
|
||||
use msg::compositor_msg::{PaintState, ReadyState};
|
||||
use msg::constellation_msg::{KeyState, LoadData};
|
||||
use msg::constellation_msg::{Key, KeyModifiers};
|
||||
use msg::constellation_msg::{SHIFT, ALT, CONTROL, SUPER};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::comm::Receiver;
|
||||
use std::num::Float;
|
||||
use std::rc::Rc;
|
||||
use time::{self, Timespec};
|
||||
use util::cursor::Cursor;
|
||||
use util::geometry::ScreenPx;
|
||||
|
||||
/// The type of a window.
|
||||
pub struct Window {
|
||||
glfw: glfw::Glfw,
|
||||
|
||||
glfw_window: glfw::Window,
|
||||
events: Receiver<(f64, glfw::WindowEvent)>,
|
||||
|
||||
event_queue: RefCell<Vec<WindowEvent>>,
|
||||
|
||||
mouse_down_button: Cell<Option<glfw::MouseButton>>,
|
||||
mouse_down_point: Cell<Point2D<c_int>>,
|
||||
|
||||
ready_state: Cell<ReadyState>,
|
||||
paint_state: Cell<PaintState>,
|
||||
|
||||
last_title_set_time: Cell<Timespec>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
/// Creates a new window.
|
||||
pub fn new(glfw: glfw::Glfw, is_foreground: bool, size: TypedSize2D<DevicePixel, uint>)
|
||||
-> Rc<Window> {
|
||||
// Create the GLFW window.
|
||||
let window_size = size.to_untyped();
|
||||
glfw.window_hint(glfw::WindowHint::Visible(is_foreground));
|
||||
let (glfw_window, events) = glfw.create_window(window_size.width as u32,
|
||||
window_size.height as u32,
|
||||
"Servo",
|
||||
glfw::WindowMode::Windowed)
|
||||
.expect("Failed to create GLFW window");
|
||||
glfw_window.make_current();
|
||||
|
||||
gl::load_with(|s| glfw_window.get_proc_address(s));
|
||||
|
||||
// Create our window object.
|
||||
let window = Window {
|
||||
glfw: glfw,
|
||||
|
||||
glfw_window: glfw_window,
|
||||
events: events,
|
||||
|
||||
event_queue: RefCell::new(vec!()),
|
||||
|
||||
mouse_down_button: Cell::new(None),
|
||||
mouse_down_point: Cell::new(Point2D(0 as c_int, 0)),
|
||||
|
||||
ready_state: Cell::new(ReadyState::Blank),
|
||||
paint_state: Cell::new(PaintState::Idle),
|
||||
|
||||
last_title_set_time: Cell::new(Timespec::new(0, 0)),
|
||||
};
|
||||
|
||||
// Register event handlers.
|
||||
window.glfw_window.set_framebuffer_size_polling(true);
|
||||
window.glfw_window.set_refresh_polling(true);
|
||||
window.glfw_window.set_key_polling(true);
|
||||
window.glfw_window.set_mouse_button_polling(true);
|
||||
window.glfw_window.set_cursor_pos_polling(true);
|
||||
window.glfw_window.set_scroll_polling(true);
|
||||
|
||||
window.glfw.set_swap_interval(1);
|
||||
|
||||
Rc::new(window)
|
||||
}
|
||||
|
||||
pub fn wait_events(&self) -> WindowEvent {
|
||||
self.wait_or_poll_events(|glfw| glfw.wait_events())
|
||||
}
|
||||
|
||||
pub fn poll_events(&self) -> WindowEvent {
|
||||
self.wait_or_poll_events(|glfw| glfw.poll_events())
|
||||
}
|
||||
|
||||
/// Helper method to factor out functionality from `poll_events` and `wait_events`.
|
||||
fn wait_or_poll_events(&self, callback: |glfw: &glfw::Glfw|) -> WindowEvent {
|
||||
{
|
||||
let mut event_queue = self.event_queue.borrow_mut();
|
||||
if !event_queue.is_empty() {
|
||||
return event_queue.remove(0).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
callback(&self.glfw);
|
||||
for (_, event) in glfw::flush_messages(&self.events) {
|
||||
self.handle_window_event(&self.glfw_window, event);
|
||||
}
|
||||
|
||||
if self.glfw_window.should_close() {
|
||||
WindowEvent::Quit
|
||||
} else {
|
||||
self.event_queue.borrow_mut().remove(0).unwrap_or(WindowEvent::Idle)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn set_nested_event_loop_listener(
|
||||
&self,
|
||||
listener: *mut (NestedEventLoopListener + 'static)) {
|
||||
self.glfw_window.set_refresh_polling(false);
|
||||
glfw::ffi::glfwSetWindowRefreshCallback(self.glfw_window.ptr, Some(on_refresh));
|
||||
glfw::ffi::glfwSetFramebufferSizeCallback(self.glfw_window.ptr, Some(on_framebuffer_size));
|
||||
g_nested_event_loop_listener = Some(listener)
|
||||
}
|
||||
|
||||
pub unsafe fn remove_nested_event_loop_listener(&self) {
|
||||
glfw::ffi::glfwSetWindowRefreshCallback(self.glfw_window.ptr, None);
|
||||
glfw::ffi::glfwSetFramebufferSizeCallback(self.glfw_window.ptr, None);
|
||||
self.glfw_window.set_refresh_polling(true);
|
||||
g_nested_event_loop_listener = None
|
||||
}
|
||||
}
|
||||
|
||||
static mut g_nested_event_loop_listener: Option<*mut (NestedEventLoopListener + 'static)> = None;
|
||||
|
||||
impl WindowMethods for Window {
|
||||
/// Returns the size of the window in hardware pixels.
|
||||
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint> {
|
||||
let (width, height) = self.glfw_window.get_framebuffer_size();
|
||||
TypedSize2D(width as uint, height as uint)
|
||||
}
|
||||
|
||||
/// Returns the size of the window in density-independent "px" units.
|
||||
fn size(&self) -> TypedSize2D<ScreenPx, f32> {
|
||||
let (width, height) = self.glfw_window.get_size();
|
||||
TypedSize2D(width as f32, height as f32)
|
||||
}
|
||||
|
||||
/// Presents the window to the screen (perhaps by page flipping).
|
||||
fn present(&self) {
|
||||
self.glfw_window.swap_buffers();
|
||||
}
|
||||
|
||||
/// Sets the ready state.
|
||||
fn set_ready_state(&self, ready_state: ReadyState) {
|
||||
self.ready_state.set(ready_state);
|
||||
self.update_window_title()
|
||||
}
|
||||
|
||||
/// Sets the paint state.
|
||||
fn set_paint_state(&self, paint_state: PaintState) {
|
||||
self.paint_state.set(paint_state);
|
||||
self.update_window_title()
|
||||
}
|
||||
|
||||
fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> {
|
||||
let backing_size = self.framebuffer_size().width.get();
|
||||
let window_size = self.size().width.get();
|
||||
ScaleFactor((backing_size as f32) / window_size)
|
||||
}
|
||||
|
||||
#[cfg(target_os="linux")]
|
||||
fn native_metadata(&self) -> NativeGraphicsMetadata {
|
||||
NativeGraphicsMetadata {
|
||||
display: unsafe { glfw::ffi::glfwGetX11Display() },
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
fn native_metadata(&self) -> NativeGraphicsMetadata {
|
||||
use cgl::{CGLGetCurrentContext, CGLGetPixelFormat};
|
||||
unsafe {
|
||||
NativeGraphicsMetadata {
|
||||
pixel_format: CGLGetPixelFormat(CGLGetCurrentContext()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_compositor_channel(_: &Option<Rc<Window>>)
|
||||
-> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) {
|
||||
let (sender, receiver) = channel();
|
||||
(box GlfwCompositorProxy {
|
||||
sender: sender,
|
||||
} as Box<CompositorProxy+Send>,
|
||||
box receiver as Box<CompositorReceiver>)
|
||||
}
|
||||
|
||||
|
||||
/// Helper function to handle keyboard events.
|
||||
fn handle_key(&self, key: Key, mods: KeyModifiers) {
|
||||
match key {
|
||||
Key::Escape => self.glfw_window.set_should_close(true),
|
||||
Key::Equal if mods.contains(CONTROL) => { // Ctrl-+
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.1));
|
||||
}
|
||||
Key::Minus if mods.contains(CONTROL) => { // Ctrl--
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.0/1.1));
|
||||
}
|
||||
Key::Backspace if mods.contains(SHIFT) => { // Shift-Backspace
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward));
|
||||
}
|
||||
Key::Backspace => { // Backspace
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back));
|
||||
}
|
||||
Key::PageDown => {
|
||||
let (_, height) = self.glfw_window.get_size();
|
||||
self.scroll_window(0.0, -height as f32);
|
||||
}
|
||||
Key::PageUp => {
|
||||
let (_, height) = self.glfw_window.get_size();
|
||||
self.scroll_window(0.0, height as f32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_for_composite(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn set_cursor(&self, _: Cursor) {
|
||||
// No-op. We could take over mouse handling ourselves and draw the cursor as an extra
|
||||
// layer with our own custom bitmaps or something, but it doesn't seem worth the
|
||||
// trouble.
|
||||
}
|
||||
|
||||
fn load_end(&self) {}
|
||||
|
||||
fn set_page_title(&self, _: Option<String>) {}
|
||||
|
||||
fn set_page_load_data(&self, _: LoadData) {}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
fn handle_window_event(&self, window: &glfw::Window, event: glfw::WindowEvent) {
|
||||
match event {
|
||||
glfw::WindowEvent::Key(key, _, action, mods) => {
|
||||
let key = glfw_key_to_script_key(key);
|
||||
let state = match action {
|
||||
glfw::Action::Press => KeyState::Pressed,
|
||||
glfw::Action::Release => KeyState::Released,
|
||||
glfw::Action::Repeat => KeyState::Repeated,
|
||||
};
|
||||
let modifiers = glfw_mods_to_script_mods(mods);
|
||||
self.event_queue.borrow_mut().push(WindowEvent::KeyEvent(key, state, modifiers));
|
||||
},
|
||||
glfw::WindowEvent::FramebufferSize(width, height) => {
|
||||
self.event_queue.borrow_mut().push(
|
||||
WindowEvent::Resize(TypedSize2D(width as uint, height as uint)));
|
||||
},
|
||||
glfw::WindowEvent::Refresh => {
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Refresh);
|
||||
},
|
||||
glfw::WindowEvent::MouseButton(button, action, _mods) => {
|
||||
let cursor_position = self.cursor_position();
|
||||
match button {
|
||||
glfw::MouseButton::Button5 => { // Back button (might be different per platform)
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back));
|
||||
},
|
||||
glfw::MouseButton::Button6 => { // Forward
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward));
|
||||
},
|
||||
glfw::MouseButtonLeft | glfw::MouseButtonRight => {
|
||||
self.handle_mouse(button,
|
||||
action,
|
||||
cursor_position.x.get() as i32,
|
||||
cursor_position.y.get() as i32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
glfw::WindowEvent::CursorPos(..) => {
|
||||
self.event_queue
|
||||
.borrow_mut()
|
||||
.push(WindowEvent::MouseWindowMoveEventClass(self.cursor_position()));
|
||||
},
|
||||
glfw::WindowEvent::Scroll(xpos, ypos) => {
|
||||
match (window.get_key(glfw::Key::LeftControl),
|
||||
window.get_key(glfw::Key::RightControl)) {
|
||||
(glfw::Action::Press, _) | (_, glfw::Action::Press) => {
|
||||
// Ctrl-Scrollwheel simulates a "pinch zoom" gesture.
|
||||
if ypos < 0.0 {
|
||||
self.event_queue.borrow_mut().push(WindowEvent::PinchZoom(1.0/1.1));
|
||||
} else if ypos > 0.0 {
|
||||
self.event_queue.borrow_mut().push(WindowEvent::PinchZoom(1.1));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let dx = (xpos as f32) * 30.0;
|
||||
let dy = (ypos as f32) * 30.0;
|
||||
self.scroll_window(dx, dy);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to send a scroll event.
|
||||
fn scroll_window(&self, dx: f32, dy: f32) {
|
||||
let cursor_pos = self.cursor_position().cast().unwrap();
|
||||
self.event_queue.borrow_mut().push(WindowEvent::Scroll(TypedPoint2D(dx, dy), cursor_pos));
|
||||
}
|
||||
|
||||
/// Helper function to set the window title in accordance with the ready state.
|
||||
fn update_window_title(&self) {
|
||||
let now = time::get_time();
|
||||
if now.sec == self.last_title_set_time.get().sec {
|
||||
return
|
||||
}
|
||||
self.last_title_set_time.set(now);
|
||||
|
||||
match self.ready_state.get() {
|
||||
ReadyState::Blank => {
|
||||
self.glfw_window.set_title("blank — Servo [GLFW]")
|
||||
}
|
||||
ReadyState::Loading => {
|
||||
self.glfw_window.set_title("Loading — Servo [GLFW]")
|
||||
}
|
||||
ReadyState::PerformingLayout => {
|
||||
self.glfw_window.set_title("Performing Layout — Servo [GLFW]")
|
||||
}
|
||||
ReadyState::FinishedLoading => {
|
||||
match self.paint_state.get() {
|
||||
PaintState::Painting => {
|
||||
self.glfw_window.set_title("Rendering — Servo [GLFW]")
|
||||
}
|
||||
PaintState::Idle => {
|
||||
self.glfw_window.set_title("Servo [GLFW]")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to handle a click
|
||||
fn handle_mouse(&self, button: glfw::MouseButton, action: glfw::Action, x: c_int, y: c_int) {
|
||||
// FIXME(tkuehn): max pixel dist should be based on pixel density
|
||||
let max_pixel_dist = 10f64;
|
||||
let event = match action {
|
||||
glfw::Action::Press => {
|
||||
self.mouse_down_point.set(Point2D(x, y));
|
||||
self.mouse_down_button.set(Some(button));
|
||||
MouseWindowEvent::MouseDown(button as uint, TypedPoint2D(x as f32, y as f32))
|
||||
}
|
||||
glfw::Action::Release => {
|
||||
match self.mouse_down_button.get() {
|
||||
None => (),
|
||||
Some(but) if button == but => {
|
||||
let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
|
||||
let pixel_dist = ((pixel_dist.x * pixel_dist.x +
|
||||
pixel_dist.y * pixel_dist.y) as f64).sqrt();
|
||||
if pixel_dist < max_pixel_dist {
|
||||
let click_event = MouseWindowEvent::Click(
|
||||
button as uint, TypedPoint2D(x as f32, y as f32));
|
||||
self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(click_event));
|
||||
}
|
||||
}
|
||||
Some(_) => (),
|
||||
}
|
||||
MouseWindowEvent::MouseUp(button as uint, TypedPoint2D(x as f32, y as f32))
|
||||
}
|
||||
_ => panic!("I cannot recognize the type of mouse action that occured. :-(")
|
||||
};
|
||||
self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(event));
|
||||
}
|
||||
|
||||
/// Returns the cursor position, properly accounting for HiDPI.
|
||||
fn cursor_position(&self) -> TypedPoint2D<DevicePixel,f32> {
|
||||
// Handle hidpi displays, since GLFW returns non-hi-def coordinates.
|
||||
let (x, y) = self.glfw_window.get_cursor_pos();
|
||||
let hidpi_factor = self.hidpi_factor();
|
||||
Point2D::from_untyped(&Point2D(x as f32, y as f32)) * hidpi_factor
|
||||
}
|
||||
}
|
||||
|
||||
struct GlfwCompositorProxy {
|
||||
sender: Sender<compositor_task::Msg>,
|
||||
}
|
||||
|
||||
impl CompositorProxy for GlfwCompositorProxy {
|
||||
fn send(&mut self, msg: compositor_task::Msg) {
|
||||
// Send a message and kick the OS event loop awake.
|
||||
self.sender.send(msg);
|
||||
glfw::Glfw::post_empty_event()
|
||||
}
|
||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy+Send> {
|
||||
box GlfwCompositorProxy {
|
||||
sender: self.sender.clone(),
|
||||
} as Box<CompositorProxy+Send>
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn on_refresh(_glfw_window: *mut glfw::ffi::GLFWwindow) {
|
||||
unsafe {
|
||||
match g_nested_event_loop_listener {
|
||||
None => {}
|
||||
Some(listener) => {
|
||||
(*listener).handle_event_from_nested_event_loop(WindowEvent::Refresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn on_framebuffer_size(_glfw_window: *mut glfw::ffi::GLFWwindow,
|
||||
width: c_int,
|
||||
height: c_int) {
|
||||
unsafe {
|
||||
match g_nested_event_loop_listener {
|
||||
None => {}
|
||||
Some(listener) => {
|
||||
let size = TypedSize2D(width as uint, height as uint);
|
||||
(*listener).handle_event_from_nested_event_loop(WindowEvent::Resize(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn glfw_mods_to_script_mods(mods: glfw::Modifiers) -> KeyModifiers {
|
||||
let mut result = KeyModifiers::from_bits(0).unwrap();
|
||||
if mods.contains(glfw::Shift) {
|
||||
result.insert(SHIFT);
|
||||
}
|
||||
if mods.contains(glfw::Alt) {
|
||||
result.insert(ALT);
|
||||
}
|
||||
if mods.contains(glfw::Control) {
|
||||
result.insert(CONTROL);
|
||||
}
|
||||
if mods.contains(glfw::Super) {
|
||||
result.insert(SUPER);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
macro_rules! glfw_keys_to_script_keys(
|
||||
($key:expr, $($name:ident),+) => (
|
||||
match $key {
|
||||
$(glfw::Key::$name => Key::$name,)+
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
fn glfw_key_to_script_key(key: glfw::Key) -> Key {
|
||||
glfw_keys_to_script_keys!(key,
|
||||
Space,
|
||||
Apostrophe,
|
||||
Comma,
|
||||
Minus,
|
||||
Period,
|
||||
Slash,
|
||||
Num0,
|
||||
Num1,
|
||||
Num2,
|
||||
Num3,
|
||||
Num4,
|
||||
Num5,
|
||||
Num6,
|
||||
Num7,
|
||||
Num8,
|
||||
Num9,
|
||||
Semicolon,
|
||||
Equal,
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
LeftBracket,
|
||||
Backslash,
|
||||
RightBracket,
|
||||
GraveAccent,
|
||||
World1,
|
||||
World2,
|
||||
|
||||
Escape,
|
||||
Enter,
|
||||
Tab,
|
||||
Backspace,
|
||||
Insert,
|
||||
Delete,
|
||||
Right,
|
||||
Left,
|
||||
Down,
|
||||
Up,
|
||||
PageUp,
|
||||
PageDown,
|
||||
Home,
|
||||
End,
|
||||
CapsLock,
|
||||
ScrollLock,
|
||||
NumLock,
|
||||
PrintScreen,
|
||||
Pause,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
F16,
|
||||
F17,
|
||||
F18,
|
||||
F19,
|
||||
F20,
|
||||
F21,
|
||||
F22,
|
||||
F23,
|
||||
F24,
|
||||
F25,
|
||||
Kp0,
|
||||
Kp1,
|
||||
Kp2,
|
||||
Kp3,
|
||||
Kp4,
|
||||
Kp5,
|
||||
Kp6,
|
||||
Kp7,
|
||||
Kp8,
|
||||
Kp9,
|
||||
KpDecimal,
|
||||
KpDivide,
|
||||
KpMultiply,
|
||||
KpSubtract,
|
||||
KpAdd,
|
||||
KpEnter,
|
||||
KpEqual,
|
||||
LeftShift,
|
||||
LeftControl,
|
||||
LeftAlt,
|
||||
LeftSuper,
|
||||
RightShift,
|
||||
RightControl,
|
||||
RightAlt,
|
||||
RightSuper,
|
||||
Menu)
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
//! A simple application that uses GLFW to open a window for Servo to display in.
|
||||
//! A simple application that uses glutin to open a window for Servo to display in.
|
||||
|
||||
#![feature(box_syntax, int_uint)]
|
||||
#![deny(unused_imports, unused_variables)]
|
||||
|
|
|
@ -74,7 +74,7 @@ class MachCommands(CommandBase):
|
|||
|
||||
if is_headless_build():
|
||||
opts += ["--no-default-features"]
|
||||
features += ["glutin_app", "headless"]
|
||||
features += ["headless"]
|
||||
|
||||
if android:
|
||||
features += ["android_glue"]
|
||||
|
@ -144,7 +144,7 @@ class MachCommands(CommandBase):
|
|||
self.ensure_bootstrapped()
|
||||
args = ["cargo", "test", "--no-run"]
|
||||
if is_headless_build():
|
||||
args += ["--no-default-features", "--features", "glutin_app headless"]
|
||||
args += ["--no-default-features", "--features", "headless"]
|
||||
return subprocess.call(
|
||||
args,
|
||||
env=self.build_env(), cwd=self.servo_crate())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue