mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #22057 - asajeffrey:magicleap-fwd-back-buttons, r=jdm
Magic Leap history traversal <!-- Please describe your changes on the following line: --> Hook up the back and forward buttons in the Magic Leap Servo2D application to history traversal. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not require tests because we can't test ML <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22057) <!-- Reviewable:end -->
This commit is contained in:
commit
cc0ac89e1a
3 changed files with 67 additions and 25 deletions
|
@ -24,7 +24,6 @@ use servo::embedder_traits::EmbedderMsg;
|
||||||
use servo::embedder_traits::EventLoopWaker;
|
use servo::embedder_traits::EventLoopWaker;
|
||||||
use servo::embedder_traits::resources::Resource;
|
use servo::embedder_traits::resources::Resource;
|
||||||
use servo::embedder_traits::resources::ResourceReaderMethods;
|
use servo::embedder_traits::resources::ResourceReaderMethods;
|
||||||
use servo::euclid::Length;
|
|
||||||
use servo::euclid::TypedPoint2D;
|
use servo::euclid::TypedPoint2D;
|
||||||
use servo::euclid::TypedRect;
|
use servo::euclid::TypedRect;
|
||||||
use servo::euclid::TypedScale;
|
use servo::euclid::TypedScale;
|
||||||
|
@ -32,21 +31,18 @@ use servo::euclid::TypedSize2D;
|
||||||
use servo::gl;
|
use servo::gl;
|
||||||
use servo::gl::Gl;
|
use servo::gl::Gl;
|
||||||
use servo::gl::GlesFns;
|
use servo::gl::GlesFns;
|
||||||
|
use servo::msg::constellation_msg::TraversalDirection;
|
||||||
use servo::script_traits::MouseButton;
|
use servo::script_traits::MouseButton;
|
||||||
use servo::servo_url::ServoUrl;
|
use servo::servo_url::ServoUrl;
|
||||||
use servo::style_traits::DevicePixel;
|
|
||||||
use servo::webrender_api::DevicePoint;
|
use servo::webrender_api::DevicePoint;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::os::raw::c_void;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
type ServoInstance = *mut c_void;
|
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum MLLogLevel {
|
pub enum MLLogLevel {
|
||||||
Fatal = 0,
|
Fatal = 0,
|
||||||
|
@ -70,7 +66,7 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
|
||||||
url: *const c_char,
|
url: *const c_char,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
hidpi: f32) -> ServoInstance
|
hidpi: f32) -> *mut ServoInstance
|
||||||
{
|
{
|
||||||
// Servo initialization goes here!
|
// Servo initialization goes here!
|
||||||
servo::embedder_traits::resources::set(Box::new(ResourceReaderInstance::new()));
|
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");
|
info!("Starting servo");
|
||||||
let mut servo = Box::new(Servo::new(window));
|
let mut servo = Servo::new(window);
|
||||||
|
|
||||||
let browser_id = BrowserId::new();
|
let browser_id = BrowserId::new();
|
||||||
|
|
||||||
let blank_url = ServoUrl::parse("about:blank").expect("Failed to parse about:blank!");
|
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 = CStr::from_ptr(url).to_str().unwrap_or("about:blank");
|
||||||
let url = ServoUrl::parse(url).unwrap_or(blank_url);
|
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),
|
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]
|
#[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!
|
// Servo heartbeat goes here!
|
||||||
if let Some(servo) = (servo as *mut Servo<WindowInstance>).as_mut() {
|
if let Some(servo) = servo.as_mut() {
|
||||||
servo.handle_events(vec![]);
|
servo.servo.handle_events(vec![]);
|
||||||
for ((_browser_id, event)) in servo.get_events() {
|
for ((_browser_id, event)) in servo.servo.get_events() {
|
||||||
match event {
|
match event {
|
||||||
// Respond to any messages with a response channel
|
// Respond to any messages with a response channel
|
||||||
// to avoid deadlocking the constellation
|
// to avoid deadlocking the constellation
|
||||||
|
@ -156,27 +156,47 @@ pub unsafe extern "C" fn heartbeat_servo(servo: ServoInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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
|
// 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 point = DevicePoint::new(x, y);
|
||||||
let window_event = if trigger {
|
let window_event = if trigger {
|
||||||
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, point))
|
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, point))
|
||||||
} else {
|
} else {
|
||||||
WindowEvent::MouseWindowMoveEventClass(point)
|
WindowEvent::MouseWindowMoveEventClass(point)
|
||||||
};
|
};
|
||||||
servo.handle_events(vec![window_event]);
|
servo.servo.handle_events(vec![window_event]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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!
|
// Servo drop goes here!
|
||||||
if !servo.is_null() {
|
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 {
|
struct WindowInstance {
|
||||||
ctxt: EGLContext,
|
ctxt: EGLContext,
|
||||||
surf: EGLSurface,
|
surf: EGLSurface,
|
||||||
|
@ -192,7 +212,7 @@ impl WindowMethods for WindowInstance {
|
||||||
SwapBuffers(self.disp, self.surf);
|
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);
|
MakeCurrent(self.disp, self.surf, self.surf, self.ctxt);
|
||||||
self.gl.viewport(0, 0, self.width as i32, self.height as i32);
|
self.gl.viewport(0, 0, self.width as i32, self.height as i32);
|
||||||
true
|
true
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <lumin/resource/PlanarResource.h>
|
#include <lumin/resource/PlanarResource.h>
|
||||||
#include <SceneDescriptor.h>
|
#include <SceneDescriptor.h>
|
||||||
|
|
||||||
typedef void* ServoInstance;
|
typedef struct Opaque ServoInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servo2D Landscape Application
|
* Servo2D Landscape Application
|
||||||
|
@ -104,5 +104,5 @@ private:
|
||||||
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
|
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
|
||||||
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
|
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
|
||||||
lumin::QuadNode* content_node_ = nullptr; // the node containing the plane
|
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
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <lumin/node/RootNode.h>
|
#include <lumin/node/RootNode.h>
|
||||||
#include <lumin/node/QuadNode.h>
|
#include <lumin/node/QuadNode.h>
|
||||||
#include <lumin/ui/Cursor.h>
|
#include <lumin/ui/Cursor.h>
|
||||||
|
#include <lumin/ui/node/UiButton.h>
|
||||||
#include <ml_logging.h>
|
#include <ml_logging.h>
|
||||||
#include <scenesGen.h>
|
#include <scenesGen.h>
|
||||||
#include <SceneDescriptor.h>
|
#include <SceneDescriptor.h>
|
||||||
|
@ -36,11 +37,12 @@ void logger(MLLogLevel lvl, char* msg) {
|
||||||
|
|
||||||
// The functions Servo provides for hooking up to the ML.
|
// The functions Servo provides for hooking up to the ML.
|
||||||
// For the moment, this doesn't handle input events.
|
// 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);
|
const char* url, int width, int height, float hidpi);
|
||||||
extern "C" void heartbeat_servo(ServoInstance);
|
extern "C" void heartbeat_servo(ServoInstance*);
|
||||||
extern "C" void cursor_servo(ServoInstance, float x, float y, bool triggered);
|
extern "C" void cursor_servo(ServoInstance*, float x, float y, bool triggered);
|
||||||
extern "C" void discard_servo(ServoInstance);
|
extern "C" void traverse_servo(ServoInstance*, int delta);
|
||||||
|
extern "C" void discard_servo(ServoInstance*);
|
||||||
|
|
||||||
// Create a Servo2D instance
|
// Create a Servo2D instance
|
||||||
Servo2D::Servo2D() {
|
Servo2D::Servo2D() {
|
||||||
|
@ -125,6 +127,26 @@ int Servo2D::init() {
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue