зеркало из https://github.com/mozilla/gecko-dev.git
157 строки
6.0 KiB
Rust
157 строки
6.0 KiB
Rust
/* 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/. */
|
|
|
|
#![macro_use]
|
|
|
|
|
|
macro_rules! check_ptr_exist {
|
|
($var:expr, $member:ident) => (
|
|
unsafe { (*CefWrap::to_c($var)).$member.is_some() }
|
|
);
|
|
}
|
|
|
|
// Provides the implementation of a CEF class. An example follows:
|
|
//
|
|
// struct ServoCefThing {
|
|
// ...
|
|
// }
|
|
//
|
|
// cef_class_impl! {
|
|
// ServoCefThing : CefThing, cef_thing_t {
|
|
// // Declare method implementations using the *C* API. (This may change later, once we
|
|
// // have associated types in Rust.)
|
|
// //
|
|
// // Note that if the method returns unit, you must write `-> ()` explicitly. This is
|
|
// // due to limitations of Rust's macro system.
|
|
// fn foo(&this, a: isize, b: *mut cef_other_thing_t) -> () {
|
|
// // Inside here, `a` will have type `isize`, and `b` will have the type
|
|
// // `CefOtherThing` -- i.e. the Rust-wrapped version of `cef_other_thing_t`.
|
|
// ...
|
|
// }
|
|
//
|
|
// fn bar(&this, a: isize) -> *mut cef_other_thing_t {
|
|
// // Return types are automatically unwrapped from the Rust types (e.g.
|
|
// // `CefOtherThing`) into the corresponding C types (e.g. `*mut
|
|
// // cef_other_thing_t`).
|
|
// let x: CefOtherThing = ...;
|
|
// x
|
|
// }
|
|
// }
|
|
// }
|
|
macro_rules! cef_class_impl(
|
|
($class_name:ident : $interface_name:ident, $c_interface_name:ident {
|
|
$(
|
|
fn $method_name:ident ( & $method_this:ident ,
|
|
$( $method_arg_name:ident : $c_method_arg_type:ty ,)* )
|
|
-> $method_return_type:ty {$method_body:block}
|
|
)*
|
|
}) => (
|
|
full_cef_class_impl! {
|
|
$class_name : $interface_name, $c_interface_name {
|
|
$(fn $method_name(&$method_this,
|
|
$($method_arg_name : $c_method_arg_type [$c_method_arg_type],)*)
|
|
-> $method_return_type {
|
|
$method_body
|
|
})*
|
|
}
|
|
}
|
|
)
|
|
);
|
|
|
|
macro_rules! full_cef_class_impl(
|
|
($class_name:ident : $interface_name:ident, $c_interface_name:ident {
|
|
$(
|
|
fn $method_name:ident ( & $method_this:ident ,
|
|
$( $method_arg_name:ident : $c_method_arg_type:ty [$method_arg_type:ty] ,)* )
|
|
-> $method_return_type:ty {$method_body:block}
|
|
)*
|
|
}) => (
|
|
impl $class_name {
|
|
pub fn as_cef_interface(self) -> $interface_name {
|
|
let cef_object = unsafe {
|
|
// Calculate the offset of the reference count. This is the size of the
|
|
// structure.
|
|
let null: *const $c_interface_name = ::std::ptr::null();
|
|
let offset: *const u32 = &(*null).ref_count;
|
|
let size = (offset as ::libc::size_t) - (null as ::libc::size_t);
|
|
$interface_name::from_c_object_addref(
|
|
::eutil::create_cef_object::<$c_interface_name,$class_name>(size))
|
|
};
|
|
unsafe {
|
|
$((*cef_object.c_object()).$method_name = Some($method_name as extern "C" fn(*mut $c_interface_name, $($c_method_arg_type,)*) -> $method_return_type);)*
|
|
let extra_slot =
|
|
::std::mem::transmute::<&mut u8,
|
|
&mut $class_name>(&mut (*cef_object.c_object())
|
|
.extra);
|
|
::std::ptr::write(extra_slot, self);
|
|
}
|
|
cef_object
|
|
}
|
|
}
|
|
|
|
$(
|
|
extern "C" fn $method_name(raw_this: *mut $c_interface_name,
|
|
$($method_arg_name: $c_method_arg_type),*)
|
|
-> $method_return_type {
|
|
let $method_this = unsafe {
|
|
$interface_name::from_c_object_addref(raw_this)
|
|
};
|
|
$(
|
|
let $method_arg_name: $method_arg_type = unsafe {
|
|
::wrappers::CefWrap::to_rust($method_arg_name)
|
|
};
|
|
)*
|
|
::wrappers::CefWrap::to_c($method_body)
|
|
}
|
|
)*
|
|
|
|
impl ::eutil::Downcast<$class_name> for $interface_name {
|
|
fn downcast(&self) -> &$class_name {
|
|
unsafe {
|
|
::std::mem::transmute::<&u8,&$class_name>(&(*self.c_object()).extra)
|
|
}
|
|
}
|
|
}
|
|
)
|
|
);
|
|
|
|
macro_rules! cef_static_method_impls(
|
|
(
|
|
$(
|
|
fn $method_name:ident ( $($method_arg_name:ident : $method_arg_type:ty ),* )
|
|
-> $method_return_type:ty {$method_body:block}
|
|
)*
|
|
) => (
|
|
$(
|
|
#[no_mangle]
|
|
pub extern "C" fn $method_name($($method_arg_name: $method_arg_type),*)
|
|
-> $method_return_type {
|
|
$(
|
|
let $method_arg_name = unsafe {
|
|
::wrappers::CefWrap::to_rust($method_arg_name)
|
|
};
|
|
)*
|
|
::wrappers::CefWrap::to_c($method_body)
|
|
}
|
|
)*
|
|
)
|
|
);
|
|
|
|
macro_rules! cef_stub_static_method_impls(
|
|
(
|
|
$(
|
|
fn $method_name:ident ( $($method_arg_name:ident : $method_arg_type:ty ),* )
|
|
-> $method_return_type:ty
|
|
)*
|
|
) => (
|
|
$(
|
|
#[no_mangle]
|
|
pub extern "C" fn $method_name($(_: $method_arg_type),*)
|
|
-> $method_return_type {
|
|
panic!("unimplemented static method: {}", stringify!($method_name))
|
|
}
|
|
)*
|
|
)
|
|
);
|