#include "cef.h"
#include "../assert.h"
#include "../application/cef.h"
#include "../browser_window.h"
#include "../cef/bw_handle_map.hpp"
#include "../cef/exception.hpp"
#include "../common.h"
#include "../debug.h"
#include "impl.h"
#include <string>
#include <include/base/cef_bind.h>
#include <include/cef_browser.h>
#include <include/cef_client.h>
#include <include/cef_v8.h>
#undef GetMessage
void bw_BrowserWindowCef_sendJsToRendererProcess(
bw_BrowserWindow* bw,
CefRefPtr<CefBrowser>& cef_browser,
CefString& code,
bw_BrowserWindowJsCallbackFn cb,
void* user_data
);
char* bw_cef_errorMessage( bw_ErrCode code, const void* data );
CefWindowInfo _bw_BrowserWindow_windowInfo( bw_Window* window, int width, int height );
void bw_BrowserWindow_evalJs( bw_BrowserWindow* bw, bw_CStrSlice js, bw_BrowserWindowJsCallbackFn cb, void* user_data ) {
std::string _code = "(function () { return ";
_code.append( js.data, js.len );
_code += "; })()";
CefString code = _code;
CefRefPtr<CefBrowser> cef_browser = *(CefRefPtr<CefBrowser>*)(bw->impl.cef_ptr);
bw_BrowserWindowCef_sendJsToRendererProcess( bw, cef_browser, code, cb, user_data );
}
void bw_BrowserWindow_evalJsThreaded( bw_BrowserWindow* bw, bw_CStrSlice js, bw_BrowserWindowJsCallbackFn cb, void* user_data ) {
bw_BrowserWindow_evalJs( bw, js, cb, user_data );
}
void bw_BrowserWindowImpl_doCleanup( bw_Window* window ) {
auto bw_ptr = (bw_BrowserWindow*)window->user_data;
CefRefPtr<CefBrowser>* cef_ptr = (CefRefPtr<CefBrowser>*)bw_ptr->impl.cef_ptr;
bw::bw_handle_map.drop( *cef_ptr );
delete cef_ptr;
delete bw_ptr->impl.resource_path;
}
bw_Err bw_BrowserWindow_navigate( bw_BrowserWindow* bw, bw_CStrSlice url ) {
std::string std_str( url.data, url.len );
CefString cef_str( std_str );
CefRefPtr<CefBrowser>* cef_ptr = (CefRefPtr<CefBrowser>*)bw->impl.cef_ptr;
(*cef_ptr)->GetMainFrame()->LoadURL( cef_str );
BW_ERR_RETURN_SUCCESS;
}
void bw_BrowserWindowImpl_new(
bw_BrowserWindow* browser,
bw_BrowserWindowSource source,
int width, int height,
const bw_BrowserWindowOptions* browser_window_options,
bw_BrowserWindowCreationCallbackFn callback,
void* callback_data
) {
UNUSED(width);
UNUSED(height);
CefWindowInfo info;
CefBrowserSettings settings;
CefString source_string;
if ( !source.is_html ) {
source_string = CefString( std::string( source.data.data, source.data.len ) );
}
else {
std::string data = "data:text/html,";
data.append( source.data.data, source.data.len );
source_string = CefString( data );
}
#if defined(BW_WIN32)
RECT rect;
GetClientRect( browser->window->impl.handle, &rect );
info.SetAsChild( browser->window->impl.handle, rect );
#elif defined(BW_GTK)
CefRect rect( 0, 0, width, height );
GtkWidget* vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0);
info.SetAsChild( (long unsigned int)vbox, rect );
gtk_container_add( GTK_CONTAINER( browser->window->impl.handle ), vbox );
gtk_widget_show_all( GTK_WIDGET(browser->window->impl.handle) );
#endif
bw_BrowserWindowImpl bw;
bw.cef_ptr = 0;
bw.resource_path = 0;
if ( browser_window_options->resource_path.len != 0 ) {
bw.resource_path = new char[ browser_window_options->resource_path.len + 1 ];
memcpy( bw.resource_path, browser_window_options->resource_path.data, browser_window_options->resource_path.len );
bw.resource_path[ browser_window_options->resource_path.len ] = '\0';
}
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
dict->SetBinary( "handle", CefBinaryValue::Create( (const void*)&browser, sizeof(browser) ) );
dict->SetBinary( "callback", CefBinaryValue::Create( (const void*)&callback, sizeof(callback) ) );
dict->SetBinary( "callback-data", CefBinaryValue::Create( (const void*)&callback_data, sizeof(callback_data) ) );
dict->SetBool( "dev-tools", browser_window_options->dev_tools );
CefRefPtr<CefClient>* cef_client = (CefRefPtr<CefClient>*)browser->window->app->engine_impl.cef_client;
bool success = CefBrowserHost::CreateBrowser( info, *cef_client, source_string, settings, dict, NULL );
BW_ASSERT( success, "CefBrowserHost::CreateBrowser failed!\n" );
browser->impl = bw;
}
void bw_BrowserWindowCef_sendJsToRendererProcess(
bw_BrowserWindow* bw,
CefRefPtr<CefBrowser>& cef_browser,
CefString& code,
bw_BrowserWindowJsCallbackFn cb,
void* user_data
) {
CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("eval-js");
CefRefPtr<CefListValue> args = msg->GetArgumentList();
args->SetString( 0, code );
CefRefPtr<CefBinaryValue> bw_bin = CefBinaryValue::Create( (const void*)&bw, sizeof( bw ) );
args->SetBinary( 1, bw_bin );
CefRefPtr<CefBinaryValue> cb_bin = CefBinaryValue::Create( (const void*)&cb, sizeof( cb ) );
args->SetBinary( 2, cb_bin );
CefRefPtr<CefBinaryValue> user_data_bin = CefBinaryValue::Create( (const void*)&user_data, sizeof( user_data ) );
args->SetBinary( 3, user_data_bin );
cef_browser->GetMainFrame()->SendProcessMessage( PID_RENDERER, msg );
}
void bw_BrowserWindowImpl_onResize( const bw_Window* window, unsigned int width, unsigned int height ) {
bw_BrowserWindow* bw = (bw_BrowserWindow*)window->user_data;
if ( bw != 0 ) {
CefRefPtr<CefBrowser> cef = *(CefRefPtr<CefBrowser>*)bw->impl.cef_ptr;
#ifdef BW_WIN32
SetWindowPos( cef->GetHost()->GetWindowHandle(), 0, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE );
#elif defined(BW_GTK)
gtk_window_resize( GTK_WINDOW(bw->window->impl.handle), width, height );
#endif
}
}