serious mode engaged: start of embedding crate using FFI

current status

=============

[ ] Successfully crashing CEF

[X] Successfully not crashing CEF
This commit is contained in:
Mike Blumenkrantz 2014-02-18 09:44:25 -05:00
parent 4d188e2ccd
commit faa7f1885c
12 changed files with 504 additions and 14 deletions

View file

@ -346,6 +346,10 @@ servo: $(DEPS_servo)
$(Q)$(RUSTC) $(RFLAGS_servo) $< --crate-type dylib,rlib $(Q)$(RUSTC) $(RFLAGS_servo) $< --crate-type dylib,rlib
RFLAGS_embedding = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net -L $(B)src/components/script -L $(B)src/components/style -L $(B)src/components/msg -L $(B).. -L $(B)src/components/main -L $(B)src/components/macros -A non_camel_case_types -A unused_variable RFLAGS_embedding = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net -L $(B)src/components/script -L $(B)src/components/style -L $(B)src/components/msg -L $(B).. -L $(B)src/components/main -L $(B)src/components/macros -A non_camel_case_types -A unused_variable
ifeq ($(CFG_OSTYPE),apple-darwin)
RFLAGS_embedding += -C link-args="-Wl,-U,_tc_new -Wl,-U,_tc_newarray -Wl,-U,_tc_delete -Wl,-U,_tc_deletearray"
endif
SRC_embedding = $(call rwildcard,$(S)src/components/embedding/,*.rs) SRC_embedding = $(call rwildcard,$(S)src/components/embedding/,*.rs)
CRATE_embedding = $(S)src/components/embedding/embedding.rs CRATE_embedding = $(S)src/components/embedding/embedding.rs

View file

@ -0,0 +1,29 @@
/* 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/. */
use libc::{calloc, size_t,c_int};
use std::mem;
use types::{cef_browser_settings_t, cef_browser_t, cef_client_t, cef_request_context_t, cef_string_t, cef_window_info_t};
#[no_mangle]
pub extern "C" fn cef_browser_host_create_browser(windowInfo: *cef_window_info_t,
client: *mut cef_client_t,
url: *cef_string_t,
settings: *cef_browser_settings_t,
request_context: *mut cef_request_context_t) -> c_int {
0
}
#[no_mangle]
pub extern "C" fn cef_browser_host_create_browser_sync(windowInfo: *cef_window_info_t,
client: *mut cef_client_t,
url: *cef_string_t,
settings: *cef_browser_settings_t,
request_context: *mut cef_request_context_t) -> *mut cef_browser_t {
unsafe {
let browser = calloc(1, mem::size_of::<cef_browser_t>() as size_t) as *mut cef_browser_t;
browser
}
}

View file

@ -0,0 +1,93 @@
/* 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/. */
use libc::{calloc, c_int, size_t};
use std::mem;
use std::str;
use std::c_vec::CVec;
use std::cast::transmute;
use string::{cef_string_userfree_utf16_alloc, cef_string_utf16_set};
use types::{cef_command_line_t, cef_string_t, cef_string_userfree_t, cef_string_utf16_t};
type command_line_t = command_line;
struct command_line {
pub cl: cef_command_line_t,
pub argc: c_int,
pub argv: Vec<~str>,
}
static mut GLOBAL_CMDLINE: Option<*mut command_line_t> = None;
fn command_line_new() -> *mut command_line_t {
unsafe {
let cl = calloc(1, mem::size_of::<command_line>() as size_t) as *mut command_line_t;
(*cl).cl.base.size = mem::size_of::<cef_command_line_t>() as u64;
cl
}
}
pub fn command_line_init(argc: c_int, argv: **u8) {
unsafe {
let mut a: Vec<~str> = vec!();
for i in range(0u, argc as uint) {
a.push(str::raw::from_c_str(*argv.offset(i as int) as *i8));
}
let cl = command_line_new();
(*cl).argc = argc;
(*cl).argv = a;
(*cl).cl.get_switch_value = command_line_get_switch_value;
GLOBAL_CMDLINE = Some(cl);
}
}
#[no_mangle]
pub extern "C" fn command_line_get_switch_value(cmd: *mut cef_command_line_t, name: *cef_string_t) -> *mut cef_string_userfree_t {
if cmd.is_null() || name.is_null() {
return 0 as *mut cef_string_userfree_t;
}
unsafe {
//technically cef_string_t can be any type of character size
//but the default cef callback uses utf16, so I'm jumping on board the SS Copy
let cl: *mut command_line_t = transmute(cmd);
let cs: *cef_string_utf16_t = transmute(name);
let opt = str::from_utf16(CVec::new((*cs).str, (*cs).length as uint).as_slice()).unwrap();
//debug!("opt: {}", opt);
for s in (*cl).argv.iter() {
let o = s.trim_left_chars('-');
//debug!("arg: {}", o);
if o.starts_with(opt) {
let string = cef_string_userfree_utf16_alloc() as *mut cef_string_utf16_t;
let arg = o.slice_from(opt.len() + 1).as_bytes();
arg.with_c_str(|c_str| {
cef_string_utf16_set(transmute(c_str), arg.len() as u64, string, 1);
});
return string as *mut cef_string_userfree_t
}
}
}
return 0 as *mut cef_string_userfree_t;
}
#[no_mangle]
pub extern "C" fn cef_command_line_create() -> *mut cef_command_line_t {
unsafe {
let cl = command_line_new();
(*cl).cl.get_switch_value = command_line_get_switch_value;
transmute(cl)
}
}
#[no_mangle]
pub extern "C" fn cef_command_line_get_global() -> *mut cef_command_line_t {
unsafe {
match GLOBAL_CMDLINE {
Some(scl) => {
transmute(scl)
},
None => {
0 as *mut cef_command_line_t
}
}
}
}

View file

@ -0,0 +1,74 @@
/* 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/. */
use azure;
use command_line::command_line_init;
use eutil::fptr_is_null;
use libc::{c_int, c_void};
use native;
use servo;
use servo_util::opts;
use std::cast::transmute;
use types::{cef_app_t, cef_main_args_t, cef_settings_t};
#[no_mangle]
pub extern "C" fn cef_initialize(args: *cef_main_args_t, settings: *mut cef_settings_t,
application: *mut cef_app_t, windows_sandbox_info: *c_void) -> c_int {
if args.is_null() {
return 0;
}
unsafe {
command_line_init((*args).argc, (*args).argv);
let cb = (*application).get_browser_process_handler;
if !fptr_is_null(transmute(cb)) {
let handler = cb(application);
if handler.is_not_null() {
let hcb = (*handler).on_context_initialized;
if !fptr_is_null(transmute(hcb)) {
hcb(handler);
}
}
}
}
return 1
}
#[no_mangle]
pub extern "C" fn cef_shutdown() {
}
#[no_mangle]
pub extern "C" fn cef_run_message_loop() {
let mut urls = Vec::new();
urls.push("http://www.w3c-test.org".to_owned());
let opts = opts::Opts {
urls: urls,
render_backend: azure::azure_hl::SkiaBackend,
n_render_threads: 1,
cpu_painting: false,
tile_size: 512,
profiler_period: None,
layout_threads: 1,
//layout_threads: cmp::max(rt::default_sched_threads() * 3 / 4, 1),
exit_after_load: false,
output_file: None,
headless: false,
hard_fail: false,
bubble_widths_separately: false,
};
native::start(0, 0 as **u8, proc() {
servo::run(opts);
});
}
#[no_mangle]
pub extern "C" fn cef_quit_message_loop() {
}
#[no_mangle]
pub extern "C" fn cef_execute_process(args: *cef_main_args_t, app: *mut cef_app_t, windows_sandbox_info: *mut c_void) -> c_int {
-1
}

View file

@ -16,7 +16,6 @@ extern crate rustuv;
extern crate servo_macros = "macros"; extern crate servo_macros = "macros";
extern crate servo; extern crate servo;
extern crate alert;
extern crate azure; extern crate azure;
extern crate geom; extern crate geom;
extern crate gfx; extern crate gfx;
@ -47,4 +46,15 @@ extern crate core_graphics;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern crate core_text; extern crate core_text;
pub mod browser;
pub mod command_line;
pub mod core;
pub mod eutil;
#[cfg(target_os="linux")] #[cfg(target_os="macos")]
pub mod mem;
pub mod request;
pub mod string;
pub mod task;
pub mod types; pub mod types;
pub mod urlrequest;

View file

@ -0,0 +1,7 @@
/* 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/. */
pub fn fptr_is_null(fptr: *u8) -> bool {
fptr.is_null()
}

View file

@ -0,0 +1,54 @@
/* 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/. */
use libc::{c_void, size_t};
use std::mem;
use std::ptr::set_memory;
extern "C" {
fn tc_new(size: size_t) -> *mut c_void;
fn tc_delete(mem: *mut c_void);
fn tc_newarray(size: size_t) -> *mut c_void;
fn tc_deletearray(mem: *mut c_void);
}
pub fn newarray0<T>(nmem: size_t) -> *mut T {
let mem = newarray::<T>(nmem) as *mut T;
unsafe {
set_memory(mem, 0 as u8, nmem as uint);
}
mem
}
pub fn newarray<T>(nmem: size_t) -> *mut T {
unsafe {
tc_newarray(nmem * mem::size_of::<T>() as u64) as *mut T
}
}
pub fn new0<T>(nmem: size_t) -> *mut T {
let mem = new(nmem * mem::size_of::<T>() as u64) as *mut T;
unsafe {
set_memory(mem, 0 as u8, nmem as uint);
}
mem
}
pub fn new(size: size_t) -> *mut c_void {
unsafe {
tc_new(size)
}
}
pub fn delete(mem: *mut c_void) {
unsafe {
tc_delete(mem)
}
}
pub fn deletearray(mem: *mut c_void) {
unsafe {
tc_deletearray(mem)
}
}

View file

@ -0,0 +1,21 @@
/* 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/. */
use types::{cef_post_data_element_t, cef_post_data_t, cef_request_t};
#[no_mangle]
pub extern "C" fn cef_request_create() -> *mut cef_request_t {
0 as *mut cef_request_t
}
#[no_mangle]
pub extern "C" fn cef_post_data_create() -> *mut cef_post_data_t {
0 as *mut cef_post_data_t
}
#[no_mangle]
pub extern "C" fn cef_post_data_element_create() -> *mut cef_post_data_element_t {
0 as *mut cef_post_data_element_t
}

View file

@ -0,0 +1,177 @@
/* 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/. */
use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::cast::transmute;
use std::ptr;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};
//cef_string
#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
deletearray(str as *mut c_void)
}
#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
deletearray(str as *mut c_void)
}
#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
deletearray(str as *mut c_void)
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
cef_string_wide_clear(cs);
delete(cs as *mut c_void)
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
cef_string_utf8_clear(cs);
delete(cs as *mut c_void)
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
cef_string_utf16_clear(cs);
delete(cs as *mut c_void)
}
#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
unsafe {
if !fptr_is_null(transmute((*cs).dtor)) {
let dtor = (*cs).dtor;
dtor((*cs).str);
}
(*cs).length = 0;
(*cs).str = 0 as *mut u8;
(*cs).dtor = transmute(0 as *u8);
}
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
#![inline(never)]
new0::<cef_string_utf8_t>(1)
}
#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
cef_string_utf8_clear(output);
unsafe {
if copy != 0 {
if !src.is_null() && src_len > 0 {
(*output).str = newarray0::<u8>(src_len + 1);
if (*output).str.is_null() {
return 0;
}
ptr::copy_memory((*output).str, src, src_len as uint);
(*output).length = src_len;
(*output).dtor = string_utf8_dtor;
}
} else {
(*output).str = transmute(src);
(*output).length = src_len;
(*output).dtor = transmute(0 as *u8);
}
}
return 1;
}
#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
unsafe {
if !fptr_is_null(transmute((*cs).dtor)) {
let dtor = (*cs).dtor;
dtor((*cs).str);
}
(*cs).length = 0;
(*cs).str = 0 as *mut c_ushort;
(*cs).dtor = transmute(0 as *u8);
}
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
#![inline(never)]
new0::<cef_string_utf16_t>(1)
}
#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
cef_string_utf16_clear(output);
unsafe {
if copy != 0 {
if !src.is_null() && src_len > 0 {
(*output).str = newarray0::<c_ushort>(src_len + 1);
if (*output).str.is_null() {
return 0;
}
ptr::copy_memory((*output).str, src, src_len as uint);
(*output).length = src_len;
(*output).dtor = string_utf16_dtor;
}
} else {
(*output).str = transmute(src);
(*output).length = src_len;
(*output).dtor = transmute(0 as *u8);
}
}
return 1;
}
#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
unsafe {
if !fptr_is_null(transmute((*cs).dtor)) {
let dtor = (*cs).dtor;
dtor((*cs).str);
}
(*cs).length = 0;
(*cs).str = 0 as *mut wchar_t;
(*cs).dtor = transmute(0 as *u8);
}
}
#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
#![inline(never)]
new0::<cef_string_wide_t>(1)
}
#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
cef_string_wide_clear(output);
unsafe {
if copy != 0 {
if !src.is_null() && src_len > 0 {
(*output).str = newarray0::<wchar_t>(src_len + 1);
if (*output).str.is_null() {
return 0;
}
ptr::copy_memory((*output).str, src, src_len as uint);
(*output).length = src_len;
(*output).dtor = string_wide_dtor;
}
} else {
(*output).str = transmute(src);
(*output).length = src_len;
(*output).dtor = transmute(0 as *u8);
}
}
return 1;
}

View file

@ -0,0 +1,12 @@
/* 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/. */
use libc::c_int;
use types::cef_thread_id_t;
//FIXME: this should check the current servo task I guess?
#[no_mangle]
pub extern "C" fn cef_currently_on(tid: cef_thread_id_t) -> c_int {
1
}

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use libc::{c_uint, c_ushort, c_int, c_double, size_t, c_void, c_longlong}; use libc::{c_uint, c_ushort, c_int, c_double, size_t, c_void, c_longlong};
use libc::types::os::arch::c95::wchar_t;
pub type cef_string_map_t = c_void; pub type cef_string_map_t = c_void;
pub type cef_string_list_t = c_void; pub type cef_string_list_t = c_void;
@ -33,24 +34,27 @@ pub type cef_string_t = cef_string_utf8; //FIXME: this is #defined...
pub type cef_string_userfree_t = cef_string_t; //FIXME: this is #defined... pub type cef_string_userfree_t = cef_string_t; //FIXME: this is #defined...
pub type cef_string_utf8_t = cef_string_utf8; pub type cef_string_utf8_t = cef_string_utf8;
pub type cef_string_userfree_utf8_t = cef_string_utf8;
pub struct cef_string_utf8 { pub struct cef_string_utf8 {
pub str: *u8, pub str: *mut u8,
pub length: size_t, pub length: size_t,
pub dtor: *fn(str: *u8), pub dtor: extern "C" fn(str: *mut u8),
} }
pub type cef_string_utf16_t = cef_string_utf16; pub type cef_string_utf16_t = cef_string_utf16;
pub type cef_string_userfree_utf16_t = cef_string_utf16;
pub struct cef_string_utf16 { pub struct cef_string_utf16 {
pub str: *c_ushort, pub str: *mut c_ushort,
pub length: size_t, pub length: size_t,
pub dtor: *fn(str: *c_ushort), pub dtor: extern "C" fn(str: *mut c_ushort),
} }
pub type cef_string_wide_t = cef_string_wide; pub type cef_string_wide_t = cef_string_wide;
pub type cef_string_userfree_wide_t = cef_string_wide;
pub struct cef_string_wide { pub struct cef_string_wide {
pub str: *c_uint, //FIXME: not sure if correct... pub str: *mut wchar_t,
pub length: size_t, pub length: size_t,
pub dtor: *fn(str: *c_uint), pub dtor: extern "C" fn(str: *mut wchar_t),
} }
pub type cef_main_args_t = cef_main_args; pub type cef_main_args_t = cef_main_args;
@ -564,13 +568,6 @@ pub struct cef_settings {
/// ///
pub multi_threaded_message_loop: c_int, pub multi_threaded_message_loop: c_int,
///
// Set to true to enable windowless (off-screen) rendering support. Do not
// enable this value if the application does not use windowless rendering as
// it may reduce rendering performance on some systems.
///
pub windowless_rendering_enabled: bool,
/// ///
// Set to true (1) to disable configuration of browser process features using // Set to true (1) to disable configuration of browser process features using
// standard CEF and Chromium command-line arguments. Configuration can still // standard CEF and Chromium command-line arguments. Configuration can still

View file

@ -0,0 +1,12 @@
/* 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/. */
use types::{cef_request_t, cef_urlrequest_client_t, cef_urlrequest_t};
#[no_mangle]
pub extern "C" fn cef_urlrequest_create(request: *mut cef_request_t, client: *mut cef_urlrequest_client_t) -> *mut cef_urlrequest_t {
0 as *mut cef_urlrequest_t
}