diff options
author | Mike Blumenkrantz <zmike@samsung.com> | 2014-02-18 09:44:25 -0500 |
---|---|---|
committer | Mike Blumenkrantz <zmike@samsung.com> | 2014-05-26 16:43:10 -0400 |
commit | faa7f1885cc0aa830b2c917cf6a1dba17d523013 (patch) | |
tree | 8f4cacaf6b5e3019a38f21c996eb43a634bb3fdf | |
parent | 4d188e2ccdc382566d794c808ab6a08ab6171966 (diff) | |
download | servo-faa7f1885cc0aa830b2c917cf6a1dba17d523013.tar.gz servo-faa7f1885cc0aa830b2c917cf6a1dba17d523013.zip |
serious mode engaged: start of embedding crate using FFI
current status
=============
[ ] Successfully crashing CEF
[X] Successfully not crashing CEF
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | src/components/embedding/browser.rs | 29 | ||||
-rw-r--r-- | src/components/embedding/command_line.rs | 93 | ||||
-rw-r--r-- | src/components/embedding/core.rs | 74 | ||||
-rw-r--r-- | src/components/embedding/embedding.rs | 12 | ||||
-rw-r--r-- | src/components/embedding/eutil.rs | 7 | ||||
-rw-r--r-- | src/components/embedding/mem.rs | 54 | ||||
-rw-r--r-- | src/components/embedding/request.rs | 21 | ||||
-rw-r--r-- | src/components/embedding/string.rs | 177 | ||||
-rw-r--r-- | src/components/embedding/task.rs | 12 | ||||
-rw-r--r-- | src/components/embedding/types.rs | 23 | ||||
-rw-r--r-- | src/components/embedding/urlrequest.rs | 12 |
12 files changed, 504 insertions, 14 deletions
diff --git a/Makefile.in b/Makefile.in index 408ae1d4ff3..cb08cbfc456 100644 --- a/Makefile.in +++ b/Makefile.in @@ -346,6 +346,10 @@ servo: $(DEPS_servo) $(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 + +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) CRATE_embedding = $(S)src/components/embedding/embedding.rs diff --git a/src/components/embedding/browser.rs b/src/components/embedding/browser.rs new file mode 100644 index 00000000000..6eda47da1b2 --- /dev/null +++ b/src/components/embedding/browser.rs @@ -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 + } +} diff --git a/src/components/embedding/command_line.rs b/src/components/embedding/command_line.rs new file mode 100644 index 00000000000..153fa2f848c --- /dev/null +++ b/src/components/embedding/command_line.rs @@ -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 + } + } + } +} diff --git a/src/components/embedding/core.rs b/src/components/embedding/core.rs new file mode 100644 index 00000000000..d67e03dbaba --- /dev/null +++ b/src/components/embedding/core.rs @@ -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 +} diff --git a/src/components/embedding/embedding.rs b/src/components/embedding/embedding.rs index 830bbdb243c..601d70d4c57 100644 --- a/src/components/embedding/embedding.rs +++ b/src/components/embedding/embedding.rs @@ -16,7 +16,6 @@ extern crate rustuv; extern crate servo_macros = "macros"; extern crate servo; -extern crate alert; extern crate azure; extern crate geom; extern crate gfx; @@ -47,4 +46,15 @@ extern crate core_graphics; #[cfg(target_os="macos")] 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 urlrequest; + diff --git a/src/components/embedding/eutil.rs b/src/components/embedding/eutil.rs new file mode 100644 index 00000000000..f378d306614 --- /dev/null +++ b/src/components/embedding/eutil.rs @@ -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() +} diff --git a/src/components/embedding/mem.rs b/src/components/embedding/mem.rs new file mode 100644 index 00000000000..032d13783d5 --- /dev/null +++ b/src/components/embedding/mem.rs @@ -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) + } +} diff --git a/src/components/embedding/request.rs b/src/components/embedding/request.rs new file mode 100644 index 00000000000..546047e7df0 --- /dev/null +++ b/src/components/embedding/request.rs @@ -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 +} diff --git a/src/components/embedding/string.rs b/src/components/embedding/string.rs new file mode 100644 index 00000000000..860b5d71651 --- /dev/null +++ b/src/components/embedding/string.rs @@ -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; +} diff --git a/src/components/embedding/task.rs b/src/components/embedding/task.rs new file mode 100644 index 00000000000..825a75f92bc --- /dev/null +++ b/src/components/embedding/task.rs @@ -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 +} diff --git a/src/components/embedding/types.rs b/src/components/embedding/types.rs index ae3cace2d3a..a4f538a6bba 100644 --- a/src/components/embedding/types.rs +++ b/src/components/embedding/types.rs @@ -3,6 +3,7 @@ * 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::types::os::arch::c95::wchar_t; pub type cef_string_map_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_utf8_t = cef_string_utf8; +pub type cef_string_userfree_utf8_t = cef_string_utf8; pub struct cef_string_utf8 { - pub str: *u8, + pub str: *mut u8, 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_userfree_utf16_t = cef_string_utf16; pub struct cef_string_utf16 { - pub str: *c_ushort, + pub str: *mut c_ushort, 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_userfree_wide_t = 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 dtor: *fn(str: *c_uint), + pub dtor: extern "C" fn(str: *mut wchar_t), } pub type cef_main_args_t = cef_main_args; @@ -565,13 +569,6 @@ pub struct cef_settings { 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 // standard CEF and Chromium command-line arguments. Configuration can still // be specified using CEF data structures or via the diff --git a/src/components/embedding/urlrequest.rs b/src/components/embedding/urlrequest.rs new file mode 100644 index 00000000000..46857e3217c --- /dev/null +++ b/src/components/embedding/urlrequest.rs @@ -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 +} |