| /******************************************************************************** |
| * Copyright (c) 2020 Equo |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Guillermo Zunino, Equo - initial implementation |
| ********************************************************************************/ |
| use cef; |
| use utils; |
| #[cfg(target_os = "linux")] |
| use gtk; |
| |
| use std::os::raw::{c_int, c_void}; |
| use std::mem::size_of; |
| use std::ptr::null_mut; |
| |
| pub fn create_browser(canvas_hwnd: *mut c_void, url: &str, jclient: &mut cef::_cef_client_t, w: c_int, h: c_int, js: c_int, bg: cef::cef_color_t) -> *mut cef::cef_browser_t { |
| //println!("create_browser in {}", canvas_hwnd); |
| |
| let window_info = cef_window_info(canvas_hwnd, w, h); |
| // Browser settings. |
| // It is mandatory to set the "size" member. |
| let browser_settings = cef::_cef_browser_settings_t { |
| size: size_of::<cef::_cef_browser_settings_t>(), |
| windowless_frame_rate: 0, |
| standard_font_family: utils::cef_string_empty(), |
| fixed_font_family: utils::cef_string_empty(), |
| serif_font_family: utils::cef_string_empty(), |
| sans_serif_font_family: utils::cef_string_empty(), |
| cursive_font_family: utils::cef_string_empty(), |
| fantasy_font_family: utils::cef_string_empty(), |
| default_font_size: 0, |
| default_fixed_font_size: 0, |
| minimum_font_size: 0, |
| minimum_logical_font_size: 0, |
| default_encoding: utils::cef_string_empty(), |
| remote_fonts: cef::cef_state_t::STATE_DEFAULT, |
| javascript: if js == 0 { cef::cef_state_t::STATE_DISABLED } else { cef::cef_state_t::STATE_DEFAULT }, |
| javascript_open_windows: cef::cef_state_t::STATE_DEFAULT, |
| javascript_close_windows: cef::cef_state_t::STATE_DEFAULT, |
| javascript_access_clipboard: cef::cef_state_t::STATE_DEFAULT, |
| javascript_dom_paste: cef::cef_state_t::STATE_DEFAULT, |
| plugins: cef::cef_state_t::STATE_DEFAULT, |
| universal_access_from_file_urls: cef::cef_state_t::STATE_ENABLED, |
| file_access_from_file_urls: cef::cef_state_t::STATE_ENABLED, |
| web_security: cef::cef_state_t::STATE_DEFAULT, |
| image_loading: cef::cef_state_t::STATE_DEFAULT, |
| image_shrink_standalone_to_fit: cef::cef_state_t::STATE_DEFAULT, |
| text_area_resize: cef::cef_state_t::STATE_DEFAULT, |
| tab_to_links: cef::cef_state_t::STATE_DEFAULT, |
| local_storage: cef::cef_state_t::STATE_DEFAULT, |
| databases: cef::cef_state_t::STATE_DEFAULT, |
| application_cache: cef::cef_state_t::STATE_DEFAULT, |
| webgl: cef::cef_state_t::STATE_DEFAULT, |
| background_color: bg, |
| accept_language_list: utils::cef_string_empty() |
| }; |
| |
| let url_cef = utils::cef_string(url); |
| |
| // Create browser. |
| // println!("Calling cef_browser_host_create_browser"); |
| //if unsafe { cef::cef_browser_host_create_browser(&window_info, client, &url_cef, &browser_settings, null_mut()) } != 1 { |
| //println!("Failed calling browserHostCreateBrowser"); |
| //} |
| let browser: *mut cef::cef_browser_t = unsafe { cef::cef_browser_host_create_browser_sync(&window_info, jclient, &url_cef, &browser_settings, null_mut()) }; |
| // println!("after Calling cef_browser_host_create_browser {:?}", browser); |
| |
| assert_eq!(unsafe{(*browser).base.size}, size_of::<cef::_cef_browser_t>()); |
| // println!("browser size ok"); |
| browser |
| } |
| |
| #[cfg(target_os = "linux")] |
| fn override_system_visual(visual: *mut c_void) { |
| unsafe { |
| let xvisual = gtk::gdk_x11_visual_get_xvisual(visual); |
| //println!("xvisualid: {:?}", (*xvisual).visualid); |
| cef_override_system_visual((*xvisual).visualid); |
| } |
| } |
| |
| #[cfg(target_os = "linux")] |
| extern "C" { |
| pub fn cef_override_system_visual(visual_id: std::os::raw::c_ulong); |
| } |
| |
| #[cfg(target_os = "linux")] |
| fn cef_window_info(hwnd: *mut c_void, w: c_int, h: c_int) -> cef::_cef_window_info_t { |
| use std::os::raw::c_uint; |
| let window_info = unsafe { |
| let visual = gtk::gtk_widget_get_visual(hwnd); |
| override_system_visual(visual); |
| let parent_win = gtk::gdk_x11_window_get_xid(gtk::gtk_widget_get_window(hwnd as *mut c_void)); |
| let window_info = cef::_cef_window_info_t { |
| x: 0, |
| y: 0, |
| width: w as c_uint, |
| height: h as c_uint, |
| parent_window: parent_win, |
| windowless_rendering_enabled: 0, |
| window: 0 |
| }; |
| window_info |
| }; |
| //println!("parent {}", window_info.parent_window); |
| window_info |
| } |
| |
| #[cfg(target_os = "linux")] |
| pub fn set_window_parent(window_info: *mut cef::_cef_window_info_t, hwnd: *mut c_void, x: c_int, y: c_int, w: c_int, h: c_int) { |
| use std::os::raw::c_uint; |
| //unsafe {println!("orig window_info {} {:?}", hwnd, (*window_info)); }; |
| unsafe { |
| (*window_info).x = x as c_uint; |
| (*window_info).y = y as c_uint; |
| (*window_info).width = w as c_uint; |
| (*window_info).height = h as c_uint; |
| (*window_info).parent_window = if hwnd.is_null() { 0 } else { |
| let visual = gtk::gtk_widget_get_visual(hwnd); |
| override_system_visual(visual); |
| |
| gtk::gdk_x11_window_get_xid(gtk::gtk_widget_get_window(hwnd)) |
| }; |
| (*window_info).windowless_rendering_enabled = 0; |
| (*window_info).window = 0; |
| } |
| //unsafe { println!("new window_info {:?}", (*window_info)); }; |
| } |
| |
| #[cfg(target_os = "macos")] |
| fn cef_window_info(hwnd: *mut c_void, w: c_int, h: c_int) -> cef::_cef_window_info_t { |
| use std::os::raw::c_void; |
| let window_info = cef::_cef_window_info_t { |
| x: 0, |
| y: 0, |
| width: w, |
| height: h, |
| parent_view: hwnd, |
| windowless_rendering_enabled: 0, |
| view: 0 as *mut c_void, |
| hidden: 0, |
| window_name: cef::cef_string_t { str: null_mut(), length: 0, dtor: Option::None } |
| }; |
| //println!("parent {:?}", window_info.parent_view); |
| window_info |
| } |
| |
| #[cfg(target_os = "macos")] |
| pub fn set_window_parent(window_info: *mut cef::_cef_window_info_t, hwnd: *mut c_void, x: c_int, y: c_int, w: c_int, h: c_int) { |
| use std::os::raw::c_void; |
| //unsafe { println!("orig window_info {} {:?}", hwnd, (*window_info)); }; |
| unsafe { |
| (*window_info).x = x; |
| (*window_info).y = y; |
| (*window_info).width = w; |
| (*window_info).height = h; |
| (*window_info).parent_view = hwnd; |
| (*window_info).windowless_rendering_enabled = 0; |
| (*window_info).view = 0 as *mut c_void; |
| (*window_info).hidden = 0; |
| (*window_info).window_name = cef::cef_string_t { str: null_mut(), length: 0, dtor: Option::None }; |
| }; |
| //unsafe { println!("new window_info {:?}", (*window_info)); }; |
| } |
| |
| #[cfg(windows)] |
| fn cef_window_info(hwnd: *mut c_void, w: c_int, h: c_int) -> cef::_cef_window_info_t { |
| extern crate winapi; |
| |
| let window_info = cef::_cef_window_info_t { |
| x: 0, |
| y: 0, |
| width: w, |
| height: h, |
| parent_window: hwnd as cef::win::HWND, |
| windowless_rendering_enabled: 0, |
| window: 0 as cef::win::HWND, |
| ex_style: 0, |
| window_name: cef::cef_string_t { str: null_mut(), length: 0, dtor: Option::None }, |
| style: winapi::um::winuser::WS_CHILDWINDOW | winapi::um::winuser::WS_CLIPCHILDREN |
| | winapi::um::winuser::WS_CLIPSIBLINGS | winapi::um::winuser::WS_VISIBLE | winapi::um::winuser::WS_TABSTOP, |
| menu: 0 as cef::win::HMENU |
| }; |
| //println!("parent {:?}", window_info.parent_window); |
| window_info |
| } |
| |
| #[cfg(windows)] |
| pub fn set_window_parent(window_info: *mut cef::_cef_window_info_t, hwnd: *mut c_void, x: c_int, y: c_int, w: c_int, h: c_int) { |
| extern crate winapi; |
| unsafe { |
| //println!("orig window_info {} {:?}", hwnd, (*window_info)); |
| if x != 0 { |
| (*window_info).x = x; |
| } |
| if y != 0 { |
| (*window_info).y = y; |
| } |
| if w != 0 { |
| (*window_info).width = w; |
| } |
| if h != 0 { |
| (*window_info).height = h; |
| } |
| (*window_info).parent_window = hwnd as cef::win::HWND; |
| (*window_info).windowless_rendering_enabled = 0; |
| (*window_info).window = 0 as cef::win::HWND; |
| (*window_info).ex_style = 0; |
| (*window_info).window_name = cef::cef_string_t { str: null_mut(), length: 0, dtor: Option::None }; |
| if !hwnd.is_null() { |
| (*window_info).style = winapi::um::winuser::WS_CHILDWINDOW | winapi::um::winuser::WS_CLIPCHILDREN |
| | winapi::um::winuser::WS_CLIPSIBLINGS | winapi::um::winuser::WS_VISIBLE | winapi::um::winuser::WS_TABSTOP; |
| } |
| (*window_info).menu = 0 as cef::win::HMENU; |
| //println!("new window_info {:?}", (*window_info)); |
| }; |
| } |