Hook up the back and forward buttons to history traversal in Magic Leap Servo2D

This commit is contained in:
Alan Jeffrey 2018-10-30 12:05:19 -05:00
parent 4ead81717a
commit c8fa64b93a
3 changed files with 67 additions and 25 deletions

View file

@ -24,7 +24,6 @@ use servo::embedder_traits::EmbedderMsg;
use servo::embedder_traits::EventLoopWaker;
use servo::embedder_traits::resources::Resource;
use servo::embedder_traits::resources::ResourceReaderMethods;
use servo::euclid::Length;
use servo::euclid::TypedPoint2D;
use servo::euclid::TypedRect;
use servo::euclid::TypedScale;
@ -32,21 +31,18 @@ use servo::euclid::TypedSize2D;
use servo::gl;
use servo::gl::Gl;
use servo::gl::GlesFns;
use servo::msg::constellation_msg::TraversalDirection;
use servo::script_traits::MouseButton;
use servo::servo_url::ServoUrl;
use servo::style_traits::DevicePixel;
use servo::webrender_api::DevicePoint;
use smallvec::SmallVec;
use std::ffi::CStr;
use std::ffi::CString;
use std::io::Write;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::path::PathBuf;
use std::rc::Rc;
type ServoInstance = *mut c_void;
#[repr(u32)]
pub enum MLLogLevel {
Fatal = 0,
@ -70,7 +66,7 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
url: *const c_char,
width: u32,
height: u32,
hidpi: f32) -> ServoInstance
hidpi: f32) -> *mut ServoInstance
{
// Servo initialization goes here!
servo::embedder_traits::resources::set(Box::new(ResourceReaderInstance::new()));
@ -93,9 +89,9 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
});
info!("Starting servo");
let mut servo = Box::new(Servo::new(window));
let mut servo = Servo::new(window);
let browser_id = BrowserId::new();
let blank_url = ServoUrl::parse("about:blank").expect("Failed to parse about:blank!");
let url = CStr::from_ptr(url).to_str().unwrap_or("about:blank");
let url = ServoUrl::parse(url).unwrap_or(blank_url);
@ -103,15 +99,19 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
WindowEvent::NewBrowser(url, browser_id),
]);
Box::into_raw(servo) as ServoInstance
let result = Box::new(ServoInstance {
browser_id: browser_id,
servo: servo,
});
Box::into_raw(result)
}
#[no_mangle]
pub unsafe extern "C" fn heartbeat_servo(servo: ServoInstance) {
pub unsafe extern "C" fn heartbeat_servo(servo: *mut ServoInstance) {
// Servo heartbeat goes here!
if let Some(servo) = (servo as *mut Servo<WindowInstance>).as_mut() {
servo.handle_events(vec![]);
for ((_browser_id, event)) in servo.get_events() {
if let Some(servo) = servo.as_mut() {
servo.servo.handle_events(vec![]);
for ((_browser_id, event)) in servo.servo.get_events() {
match event {
// Respond to any messages with a response channel
// to avoid deadlocking the constellation
@ -156,27 +156,47 @@ pub unsafe extern "C" fn heartbeat_servo(servo: ServoInstance) {
}
#[no_mangle]
pub unsafe extern "C" fn cursor_servo(servo: ServoInstance, x: f32, y: f32, trigger: bool) {
pub unsafe extern "C" fn cursor_servo(servo: *mut ServoInstance, x: f32, y: f32, trigger: bool) {
// Servo was triggered
if let Some(servo) = (servo as *mut Servo<WindowInstance>).as_mut() {
if let Some(servo) = servo.as_mut() {
let point = DevicePoint::new(x, y);
let window_event = if trigger {
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, point))
} else {
WindowEvent::MouseWindowMoveEventClass(point)
};
servo.handle_events(vec![window_event]);
servo.servo.handle_events(vec![window_event]);
}
}
#[no_mangle]
pub unsafe extern "C" fn discard_servo(servo: ServoInstance) {
pub unsafe extern "C" fn traverse_servo(servo: *mut ServoInstance, delta: i32) {
// Traverse the session history
if let Some(servo) = servo.as_mut() {
let window_event = if delta == 0 {
WindowEvent::Reload(servo.browser_id)
} else if delta < 0 {
WindowEvent::Navigation(servo.browser_id, TraversalDirection::Back(-delta as usize))
} else {
WindowEvent::Navigation(servo.browser_id, TraversalDirection::Forward(delta as usize))
};
servo.servo.handle_events(vec![window_event]);
}
}
#[no_mangle]
pub unsafe extern "C" fn discard_servo(servo: *mut ServoInstance) {
// Servo drop goes here!
if !servo.is_null() {
Box::from_raw(servo as *mut Servo<WindowInstance>);
Box::from_raw(servo);
}
}
pub struct ServoInstance {
browser_id: BrowserId,
servo: Servo<WindowInstance>,
}
struct WindowInstance {
ctxt: EGLContext,
surf: EGLSurface,
@ -192,7 +212,7 @@ impl WindowMethods for WindowInstance {
SwapBuffers(self.disp, self.surf);
}
fn prepare_for_composite(&self, _w: Length<u32, DevicePixel>, _h: Length<u32, DevicePixel>) -> bool {
fn prepare_for_composite(&self) -> bool {
MakeCurrent(self.disp, self.surf, self.surf, self.ctxt);
self.gl.viewport(0, 0, self.width as i32, self.height as i32);
true

View file

@ -11,7 +11,7 @@
#include <lumin/resource/PlanarResource.h>
#include <SceneDescriptor.h>
typedef void* ServoInstance;
typedef struct Opaque ServoInstance;
/**
* Servo2D Landscape Application
@ -104,5 +104,5 @@ private:
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
lumin::QuadNode* content_node_ = nullptr; // the node containing the plane
ServoInstance servo_ = nullptr; // the servo instance we're embedding
ServoInstance* servo_ = nullptr; // the servo instance we're embedding
};

View file

@ -6,6 +6,7 @@
#include <lumin/node/RootNode.h>
#include <lumin/node/QuadNode.h>
#include <lumin/ui/Cursor.h>
#include <lumin/ui/node/UiButton.h>
#include <ml_logging.h>
#include <scenesGen.h>
#include <SceneDescriptor.h>
@ -36,11 +37,12 @@ void logger(MLLogLevel lvl, char* msg) {
// The functions Servo provides for hooking up to the ML.
// For the moment, this doesn't handle input events.
extern "C" ServoInstance init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
extern "C" ServoInstance* init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
const char* url, int width, int height, float hidpi);
extern "C" void heartbeat_servo(ServoInstance);
extern "C" void cursor_servo(ServoInstance, float x, float y, bool triggered);
extern "C" void discard_servo(ServoInstance);
extern "C" void heartbeat_servo(ServoInstance*);
extern "C" void cursor_servo(ServoInstance*, float x, float y, bool triggered);
extern "C" void traverse_servo(ServoInstance*, int delta);
extern "C" void discard_servo(ServoInstance*);
// Create a Servo2D instance
Servo2D::Servo2D() {
@ -125,6 +127,26 @@ int Servo2D::init() {
return 1;
}
// Add a callback to the back button
std::string back_button_id = Servo2D_exportedNodes::backButton;
lumin::ui::UiButton* back_button = lumin::ui::UiButton::CastFrom(prism_->findNode(back_button_id, root_node));
if (!back_button) {
ML_LOG(Error, "Servo2D Failed to get back button");
abort();
return 1;
}
back_button->onActivateSub(std::bind(traverse_servo, servo_, -1));
// Add a callback to the forward button
std::string fwd_button_id = Servo2D_exportedNodes::fwdButton;
lumin::ui::UiButton* fwd_button = lumin::ui::UiButton::CastFrom(prism_->findNode(fwd_button_id, root_node));
if (!fwd_button) {
ML_LOG(Error, "Servo2D Failed to get forward button");
abort();
return 1;
}
fwd_button->onActivateSub(std::bind(traverse_servo, servo_, +1));
return 0;
}