Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Get the ML port to follow hyperlinks
  • Loading branch information
Alan Jeffrey committed Oct 29, 2018
1 parent 0ec0f70 commit fc38c04
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 9 deletions.
59 changes: 59 additions & 0 deletions ports/libmlservo/src/lib.rs
Expand Up @@ -12,8 +12,10 @@ use servo::BrowserId;
use servo::Servo;
use servo::compositing::windowing::AnimationState;
use servo::compositing::windowing::EmbedderCoordinates;
use servo::compositing::windowing::MouseWindowEvent;
use servo::compositing::windowing::WindowEvent;
use servo::compositing::windowing::WindowMethods;
use servo::embedder_traits::EmbedderMsg;
use servo::embedder_traits::EventLoopWaker;
use servo::embedder_traits::resources::Resource;
use servo::embedder_traits::resources::ResourceReaderMethods;
Expand All @@ -25,8 +27,10 @@ use servo::euclid::TypedSize2D;
use servo::gl;
use servo::gl::Gl;
use servo::gl::GlesFns;
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;
Expand Down Expand Up @@ -98,6 +102,61 @@ pub unsafe extern "C" fn heartbeat_servo(servo: 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() {
match event {
// Respond to any messages with a response channel
// to avoid deadlocking the constellation
EmbedderMsg::AllowNavigation(_url, sender) => {
let _ = sender.send(true);
},
EmbedderMsg::GetSelectedBluetoothDevice(_, sender) => {
let _ = sender.send(None);
},
EmbedderMsg::AllowUnload(sender) => {
let _ = sender.send(true);
},
EmbedderMsg::Alert(_, sender) => {
let _ = sender.send(());
},
EmbedderMsg::AllowOpeningBrowser(sender) => {
let _ = sender.send(false);
},
// Ignore most messages for now
EmbedderMsg::ChangePageTitle(..) |
EmbedderMsg::BrowserCreated(..) |
EmbedderMsg::HistoryChanged(..) |
EmbedderMsg::LoadStart |
EmbedderMsg::LoadComplete |
EmbedderMsg::CloseBrowser |
EmbedderMsg::Status(..) |
EmbedderMsg::SelectFiles(..) |
EmbedderMsg::MoveTo(..) |
EmbedderMsg::ResizeTo(..) |
EmbedderMsg::Keyboard(..) |
EmbedderMsg::SetCursor(..) |
EmbedderMsg::NewFavicon(..) |
EmbedderMsg::HeadParsed |
EmbedderMsg::SetFullscreenState(..) |
EmbedderMsg::ShowIME(..) |
EmbedderMsg::HideIME |
EmbedderMsg::Shutdown |
EmbedderMsg::Panic(..) => {},
}
}
}
}

#[no_mangle]
pub unsafe extern "C" fn cursor_servo(servo: ServoInstance, x: f32, y: f32, trigger: bool) {
// Servo was triggered
if let Some(servo) = (servo as *mut Servo<WindowInstance>).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]);
}
}

Expand Down
1 change: 1 addition & 0 deletions support/magicleap/Servo2D/.vscode/settings.json
Expand Up @@ -5,6 +5,7 @@
"C_Cpp.default.includePath": [
"${workspaceFolder}/code/**",
"${config.lumin_sdk}/lumin/usr/include/",
"${config.lumin_sdk}/lumin/stl/libc++-lumin/include",
"${config.lumin_sdk}/include/runtime/app",
"${config.lumin_sdk}/include/runtime/core",
"${config.lumin_sdk}/include/runtime/external",
Expand Down
12 changes: 12 additions & 0 deletions support/magicleap/Servo2D/code/inc/Servo2D.h
Expand Up @@ -5,6 +5,9 @@
#include <lumin/LandscapeApp.h>
#include <lumin/Prism.h>
#include <lumin/event/ServerEvent.h>
#include <lumin/event/KeyInputEventData.h>
#include <lumin/event/ControlTouchPadInputEventData.h>
#include <lumin/node/QuadNode.h>
#include <lumin/resource/PlanarResource.h>
#include <SceneDescriptor.h>

Expand Down Expand Up @@ -88,9 +91,18 @@ class Servo2D : public lumin::LandscapeApp {
* Handle events from the server
*/
virtual bool eventListener(lumin::ServerEvent* event) override;
bool touchpadEventListener(lumin::ControlTouchPadInputEventData* event);
bool keyEventListener(lumin::KeyInputEventData* event);

/**
* Get the current cursor position, with respect to the viewport.
*/
glm::vec2 viewportCursorPosition();
bool pointInsideViewport(glm::vec2 pt);

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
};
82 changes: 73 additions & 9 deletions support/magicleap/Servo2D/code/src/Servo2D.cpp
Expand Up @@ -11,11 +11,12 @@
#include <SceneDescriptor.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <glm/gtc/matrix_transform.hpp>
#include <string.h>

// The viewport dimensions (in px).
const unsigned int VIEWPORT_W = 500;
const unsigned int VIEWPORT_H = 500;
const int VIEWPORT_W = 500;
const int VIEWPORT_H = 500;

// The hidpi factor.
const float HIDPI = 1.0;
Expand All @@ -38,6 +39,7 @@ void logger(MLLogLevel lvl, char* msg) {
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);

// Create a Servo2D instance
Expand Down Expand Up @@ -86,12 +88,13 @@ int Servo2D::init() {
}

std::string content_node_id = Servo2D_exportedNodes::content;
lumin::QuadNode* content_node = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
if (!content_node) {
content_node_ = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
if (!content_node_) {
ML_LOG(Error, "Servo2D Failed to get content node");
abort();
return 1;
}
content_node_->setTriggerable(true);

lumin::ResourceIDType plane_id = prism_->createPlanarEGLResourceId();
if (!plane_id) {
Expand All @@ -107,7 +110,7 @@ int Servo2D::init() {
return 1;
}

content_node->setRenderResource(plane_id);
content_node_->setRenderResource(plane_id);

// Get the EGL context, surface and display.
EGLContext ctx = plane_->getEGLContext();
Expand All @@ -117,7 +120,7 @@ int Servo2D::init() {
glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);

// Hook into servo
servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org", VIEWPORT_H, VIEWPORT_W, HIDPI);
servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org/", VIEWPORT_H, VIEWPORT_W, HIDPI);
if (!servo_) {
ML_LOG(Error, "Servo2D Failed to init servo instance");
abort();
Expand Down Expand Up @@ -192,9 +195,70 @@ bool Servo2D::updateLoop(float fDelta) {
}

bool Servo2D::eventListener(lumin::ServerEvent* event) {
// Dispatch based on event type
switch (event->getServerEventType()) {
case lumin::ServerEventType::kControlTouchPadInputEvent:
return touchpadEventListener(static_cast<lumin::ControlTouchPadInputEventData*>(event));
case lumin::ServerEventType::kKeyInputEvent:
return keyEventListener(static_cast<lumin::KeyInputEventData*>(event));
default:
return false;
}
}

glm::vec2 Servo2D::viewportCursorPosition() {
// Get the cursor position relative to the origin of the content node (in m)
glm::vec3 pos = lumin::ui::Cursor::GetPosition(prism_) - content_node_->getPrismPosition();

// Get the size of the content node (in m)
glm::vec2 sz = content_node_->getSize();

// Convert to a position in viewport px
float x = (pos.x / sz.x) * (float)VIEWPORT_W;
float y = (1 - pos.y / sz.y) * (float)VIEWPORT_H; // Sigh, invert the y coordinate

return glm::vec2(x, y);
}

bool Servo2D::pointInsideViewport(glm::vec2 pt) {
return (0 <= pt.x && 0 <= pt.y && pt.x <= VIEWPORT_W && pt.y <= VIEWPORT_H);
}

bool Servo2D::touchpadEventListener(lumin::ControlTouchPadInputEventData* event) {
// Only respond when the cursor is enabled
if (!lumin::ui::Cursor::IsEnabled(prism_)) {
return false;
}

// Place your event handling here.
// Only respond when the cursor is inside the viewport
glm::vec2 pos = viewportCursorPosition();
if (!pointInsideViewport(pos)) {
return false;
}

// Inform Servo of the trigger
cursor_servo(servo_, pos.x, pos.y, false);
return true;
}

bool Servo2D::keyEventListener(lumin::KeyInputEventData* event) {
// Only respond to trigger keys
if (event->keyCode() != lumin::input::KeyCodes::AKEYCODE_EX_TRIGGER) {
return false;
}

// Return true if the event is consumed.
return false;
// Only respond when the cursor is enabled
if (!lumin::ui::Cursor::IsEnabled(prism_)) {
return false;
}

// Only respond when the cursor is inside the viewport
glm::vec2 pos = viewportCursorPosition();
if (!pointInsideViewport(pos)) {
return false;
}

// Inform Servo of the trigger
cursor_servo(servo_, pos.x, pos.y, true);
return true;
}

0 comments on commit fc38c04

Please sign in to comment.