aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2014-02-18 09:44:25 -0500
committerMike Blumenkrantz <zmike@samsung.com>2014-05-26 16:43:10 -0400
commitfaa7f1885cc0aa830b2c917cf6a1dba17d523013 (patch)
tree8f4cacaf6b5e3019a38f21c996eb43a634bb3fdf
parent4d188e2ccdc382566d794c808ab6a08ab6171966 (diff)
downloadservo-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.in4
-rw-r--r--src/components/embedding/browser.rs29
-rw-r--r--src/components/embedding/command_line.rs93
-rw-r--r--src/components/embedding/core.rs74
-rw-r--r--src/components/embedding/embedding.rs12
-rw-r--r--src/components/embedding/eutil.rs7
-rw-r--r--src/components/embedding/mem.rs54
-rw-r--r--src/components/embedding/request.rs21
-rw-r--r--src/components/embedding/string.rs177
-rw-r--r--src/components/embedding/task.rs12
-rw-r--r--src/components/embedding/types.rs23
-rw-r--r--src/components/embedding/urlrequest.rs12
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
+}