Windows: Add off-screen rendering support (issue #518).

- Popup menus, drag&drop and GPU acceleration are not currently supported.
- Testing is enabled in cefclient by passing the "off-screen-rendering-enabled" command-line flag.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@919 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-11-21 00:40:15 +00:00
parent cd32e16c61
commit 6b7716f64b
58 changed files with 4108 additions and 17 deletions

14
cef.gyp
View File

@ -84,6 +84,8 @@
'-lcomctl32.lib', '-lcomctl32.lib',
'-lshlwapi.lib', '-lshlwapi.lib',
'-lrpcrt4.lib', '-lrpcrt4.lib',
'-lopengl32.lib',
'-lglu32.lib',
], ],
}, },
'sources': [ 'sources': [
@ -290,6 +292,11 @@
'.', '.',
], ],
'conditions': [ 'conditions': [
[ 'OS=="win"', {
'sources': [
'tests/unittests/os_rendering_unittest.cc',
],
}],
[ 'OS=="mac"', { [ 'OS=="mac"', {
'product_name': 'cef_unittests', 'product_name': 'cef_unittests',
'dependencies': [ 'dependencies': [
@ -936,11 +943,18 @@
['OS=="win"', { ['OS=="win"', {
'sources': [ 'sources': [
'<@(includes_win)', '<@(includes_win)',
'libcef/browser/backing_store_osr.cc',
'libcef/browser/backing_store_osr.h',
'libcef/browser/backing_store_osr_win.cc',
'libcef/browser/browser_host_impl_win.cc', 'libcef/browser/browser_host_impl_win.cc',
'libcef/browser/browser_main_win.cc', 'libcef/browser/browser_main_win.cc',
'libcef/browser/javascript_dialog_win.cc', 'libcef/browser/javascript_dialog_win.cc',
'libcef/browser/menu_creator_runner_win.cc', 'libcef/browser/menu_creator_runner_win.cc',
'libcef/browser/menu_creator_runner_win.h', 'libcef/browser/menu_creator_runner_win.h',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/web_contents_view_osr.cc',
'libcef/browser/web_contents_view_osr.h',
# Include sources for context menu implementation. # Include sources for context menu implementation.
'<(DEPTH)/ui/views/controls/menu/menu_2.cc', '<(DEPTH)/ui/views/controls/menu/menu_2.cc',
'<(DEPTH)/ui/views/controls/menu/menu_2.h', '<(DEPTH)/ui/views/controls/menu/menu_2.h',

View File

@ -39,6 +39,7 @@
'include/cef_process_message.h', 'include/cef_process_message.h',
'include/cef_process_util.h', 'include/cef_process_util.h',
'include/cef_proxy_handler.h', 'include/cef_proxy_handler.h',
'include/cef_render_handler.h',
'include/cef_render_process_handler.h', 'include/cef_render_process_handler.h',
'include/cef_request.h', 'include/cef_request.h',
'include/cef_request_handler.h', 'include/cef_request_handler.h',
@ -86,6 +87,7 @@
'include/capi/cef_process_message_capi.h', 'include/capi/cef_process_message_capi.h',
'include/capi/cef_process_util_capi.h', 'include/capi/cef_process_util_capi.h',
'include/capi/cef_proxy_handler_capi.h', 'include/capi/cef_proxy_handler_capi.h',
'include/capi/cef_render_handler_capi.h',
'include/capi/cef_render_process_handler_capi.h', 'include/capi/cef_render_process_handler_capi.h',
'include/capi/cef_request_capi.h', 'include/capi/cef_request_capi.h',
'include/capi/cef_request_handler_capi.h', 'include/capi/cef_request_handler_capi.h',
@ -194,6 +196,8 @@
'libcef_dll/cpptoc/quota_callback_cpptoc.h', 'libcef_dll/cpptoc/quota_callback_cpptoc.h',
'libcef_dll/ctocpp/read_handler_ctocpp.cc', 'libcef_dll/ctocpp/read_handler_ctocpp.cc',
'libcef_dll/ctocpp/read_handler_ctocpp.h', 'libcef_dll/ctocpp/read_handler_ctocpp.h',
'libcef_dll/ctocpp/render_handler_ctocpp.cc',
'libcef_dll/ctocpp/render_handler_ctocpp.h',
'libcef_dll/ctocpp/render_process_handler_ctocpp.cc', 'libcef_dll/ctocpp/render_process_handler_ctocpp.cc',
'libcef_dll/ctocpp/render_process_handler_ctocpp.h', 'libcef_dll/ctocpp/render_process_handler_ctocpp.h',
'libcef_dll/cpptoc/request_cpptoc.cc', 'libcef_dll/cpptoc/request_cpptoc.cc',
@ -342,6 +346,8 @@
'libcef_dll/ctocpp/quota_callback_ctocpp.h', 'libcef_dll/ctocpp/quota_callback_ctocpp.h',
'libcef_dll/cpptoc/read_handler_cpptoc.cc', 'libcef_dll/cpptoc/read_handler_cpptoc.cc',
'libcef_dll/cpptoc/read_handler_cpptoc.h', 'libcef_dll/cpptoc/read_handler_cpptoc.h',
'libcef_dll/cpptoc/render_handler_cpptoc.cc',
'libcef_dll/cpptoc/render_handler_cpptoc.h',
'libcef_dll/cpptoc/render_process_handler_cpptoc.cc', 'libcef_dll/cpptoc/render_process_handler_cpptoc.cc',
'libcef_dll/cpptoc/render_process_handler_cpptoc.h', 'libcef_dll/cpptoc/render_process_handler_cpptoc.h',
'libcef_dll/ctocpp/request_ctocpp.cc', 'libcef_dll/ctocpp/request_ctocpp.cc',

View File

@ -118,8 +118,12 @@
], ],
'cefclient_sources_win': [ 'cefclient_sources_win': [
'tests/cefclient/cefclient.rc', 'tests/cefclient/cefclient.rc',
'tests/cefclient/cefclient_osr_widget_win.h',
'tests/cefclient/cefclient_osr_widget_win.cpp',
'tests/cefclient/cefclient_win.cpp', 'tests/cefclient/cefclient_win.cpp',
'tests/cefclient/client_handler_win.cpp', 'tests/cefclient/client_handler_win.cpp',
'tests/cefclient/osrenderer.h',
'tests/cefclient/osrenderer.cpp',
'tests/cefclient/resource.h', 'tests/cefclient/resource.h',
'tests/cefclient/res/cefclient.ico', 'tests/cefclient/res/cefclient.ico',
'tests/cefclient/res/logoball.png', 'tests/cefclient/res/logoball.png',

View File

@ -290,6 +290,69 @@ typedef struct _cef_browser_host_t {
enum cef_file_dialog_mode_t mode, const cef_string_t* title, enum cef_file_dialog_mode_t mode, const cef_string_t* title,
const cef_string_t* default_file_name, cef_string_list_t accept_types, const cef_string_t* default_file_name, cef_string_list_t accept_types,
struct _cef_run_file_dialog_callback_t* callback); struct _cef_run_file_dialog_callback_t* callback);
///
// Returns true (1) if window rendering is disabled.
///
int (CEF_CALLBACK *is_window_rendering_disabled)(
struct _cef_browser_host_t* self);
///
// Notify the browser that the widget has been resized. The browser will first
// call cef_render_handler_t::GetViewRect to get the new size and then call
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
// function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *was_resized)(struct _cef_browser_host_t* self);
///
// Invalidate the |dirtyRect| region of the view. The browser will call
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
// function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *invalidate)(struct _cef_browser_host_t* self,
const cef_rect_t* dirtyRect);
///
// Send a key event to the browser.
///
void (CEF_CALLBACK *send_key_event)(struct _cef_browser_host_t* self,
const struct _cef_key_event_t* event);
///
// Send a mouse click event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view.
///
void (CEF_CALLBACK *send_mouse_click_event)(struct _cef_browser_host_t* self,
int x, int y, enum cef_mouse_button_type_t type, int mouseUp,
int clickCount);
///
// Send a mouse move event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view.
///
void (CEF_CALLBACK *send_mouse_move_event)(struct _cef_browser_host_t* self,
int x, int y, int mouseLeave);
///
// Send a mouse wheel event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view. The |deltaX| and |deltaY|
// values represent the movement delta in the X and Y directions respectively.
///
void (CEF_CALLBACK *send_mouse_wheel_event)(struct _cef_browser_host_t* self,
int x, int y, int deltaX, int deltaY);
///
// Send a focus event to the browser.
///
void (CEF_CALLBACK *send_focus_event)(struct _cef_browser_host_t* self,
int setFocus);
///
// Send a capture lost event to the browser.
///
void (CEF_CALLBACK *send_capture_lost_event)(
struct _cef_browser_host_t* self);
} cef_browser_host_t; } cef_browser_host_t;

View File

@ -119,6 +119,12 @@ typedef struct _cef_client_t {
struct _cef_load_handler_t* (CEF_CALLBACK *get_load_handler)( struct _cef_load_handler_t* (CEF_CALLBACK *get_load_handler)(
struct _cef_client_t* self); struct _cef_client_t* self);
///
// Return the handler for off-screen rendering events.
///
struct _cef_render_handler_t* (CEF_CALLBACK *get_render_handler)(
struct _cef_client_t* self);
/// ///
// Return the handler for browser request events. // Return the handler for browser request events.
/// ///

View File

@ -80,7 +80,8 @@ typedef struct _cef_display_handler_t {
// text that will be displayed in the tooltip. To handle the display of the // text that will be displayed in the tooltip. To handle the display of the
// tooltip yourself return true (1). Otherwise, you can optionally modify // tooltip yourself return true (1). Otherwise, you can optionally modify
// |text| and then return false (0) to allow the browser to display the // |text| and then return false (0) to allow the browser to display the
// tooltip. // tooltip. When window rendering is disabled the application is responsible
// for drawing tooltips and the return value is ignored.
/// ///
int (CEF_CALLBACK *on_tooltip)(struct _cef_display_handler_t* self, int (CEF_CALLBACK *on_tooltip)(struct _cef_display_handler_t* self,
struct _cef_browser_t* browser, cef_string_t* text); struct _cef_browser_t* browser, cef_string_t* text);

View File

@ -0,0 +1,122 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "include/capi/cef_base_capi.h"
///
// Implement this structure to handle events when window rendering is disabled.
// The functions of this structure will be called on the UI thread.
///
typedef struct _cef_render_handler_t {
///
// Base structure.
///
cef_base_t base;
///
// Called to retrieve the root window rectangle in screen coordinates. Return
// true (1) if the rectangle was provided. Return false (0) if the screen
// rectangle is the same as the view rectangle.
///
int (CEF_CALLBACK *get_root_screen_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the view rectangle which is relative to screen
// coordinates. Return true (1) if the rectangle was provided.
///
int (CEF_CALLBACK *get_view_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true (1) if the screen coordinates were provided.
///
int (CEF_CALLBACK *get_screen_point)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int viewX, int viewY, int* screenX,
int* screenY);
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true (1) and hidden if |show| is false (0).
// NOTE: Popup widgets are not yet supported.
///
void (CEF_CALLBACK *on_popup_show)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int show);
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size. NOTE: Popup widgets are not yet
// supported.
///
void (CEF_CALLBACK *on_popup_size)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, const cef_rect_t* rect);
///
// Called when an element should be painted. |type| indicates whether the
// element is the view or the popup widget. |buffer| contains the pixel data
// for the whole image. |dirtyRects| contains the set of rectangles that need
// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes in
// size and represents a BGRA image with an upper-left origin. NOTE: Popup
// widgets are not yet supported.
///
void (CEF_CALLBACK *on_paint)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, enum cef_paint_element_type_t type,
size_t dirtyRectsCount, cef_rect_t const* dirtyRects, const void* buffer,
int width, int height);
///
// Called when the browser window's cursor has changed.
///
void (CEF_CALLBACK *on_cursor_change)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_cursor_handle_t cursor);
} cef_render_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_

View File

@ -211,6 +211,7 @@ class CefRunFileDialogCallback : public virtual CefBase {
class CefBrowserHost : public virtual CefBase { class CefBrowserHost : public virtual CefBase {
public: public:
typedef cef_file_dialog_mode_t FileDialogMode; typedef cef_file_dialog_mode_t FileDialogMode;
typedef cef_mouse_button_type_t MouseButtonType;
/// ///
// Create a new browser window using the window parameters specified by // Create a new browser window using the window parameters specified by
@ -329,6 +330,70 @@ class CefBrowserHost : public virtual CefBase {
const CefString& default_file_name, const CefString& default_file_name,
const std::vector<CefString>& accept_types, const std::vector<CefString>& accept_types,
CefRefPtr<CefRunFileDialogCallback> callback) =0; CefRefPtr<CefRunFileDialogCallback> callback) =0;
///
// Returns true if window rendering is disabled.
///
/*--cef()--*/
virtual bool IsWindowRenderingDisabled() =0;
///
// Notify the browser that the widget has been resized. The browser will first
// call CefRenderHandler::GetViewRect to get the new size and then call
// CefRenderHandler::OnPaint asynchronously with the updated regions. This
// method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void WasResized() =0;
///
// Invalidate the |dirtyRect| region of the view. The browser will call
// CefRenderHandler::OnPaint asynchronously with the updated regions. This
// method is only used when window rendering is disabled.
///
/*--cef()--*/
virtual void Invalidate(const CefRect& dirtyRect) =0;
///
// Send a key event to the browser.
///
/*--cef()--*/
virtual void SendKeyEvent(const CefKeyEvent& event) =0;
///
// Send a mouse click event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view.
///
/*--cef()--*/
virtual void SendMouseClickEvent(int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) =0;
///
// Send a mouse move event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view.
///
/*--cef()--*/
virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) =0;
///
// Send a mouse wheel event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view. The |deltaX| and |deltaY|
// values represent the movement delta in the X and Y directions respectively.
///
/*--cef()--*/
virtual void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) =0;
///
// Send a focus event to the browser.
///
/*--cef()--*/
virtual void SendFocusEvent(bool setFocus) =0;
///
// Send a capture lost event to the browser.
///
/*--cef()--*/
virtual void SendCaptureLostEvent() =0;
}; };
#endif // CEF_INCLUDE_CEF_BROWSER_H_ #endif // CEF_INCLUDE_CEF_BROWSER_H_

View File

@ -50,6 +50,7 @@
#include "include/cef_life_span_handler.h" #include "include/cef_life_span_handler.h"
#include "include/cef_load_handler.h" #include "include/cef_load_handler.h"
#include "include/cef_process_message.h" #include "include/cef_process_message.h"
#include "include/cef_render_handler.h"
#include "include/cef_request_handler.h" #include "include/cef_request_handler.h"
/// ///
@ -143,6 +144,14 @@ class CefClient : public virtual CefBase {
return NULL; return NULL;
} }
///
// Return the handler for off-screen rendering events.
///
/*--cef()--*/
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() {
return NULL;
}
/// ///
// Return the handler for browser request events. // Return the handler for browser request events.
/// ///

View File

@ -78,6 +78,8 @@ class CefDisplayHandler : public virtual CefBase {
// text that will be displayed in the tooltip. To handle the display of the // text that will be displayed in the tooltip. To handle the display of the
// tooltip yourself return true. Otherwise, you can optionally modify |text| // tooltip yourself return true. Otherwise, you can optionally modify |text|
// and then return false to allow the browser to display the tooltip. // and then return false to allow the browser to display the tooltip.
// When window rendering is disabled the application is responsible for
// drawing tooltips and the return value is ignored.
/// ///
/*--cef(optional_param=text)--*/ /*--cef(optional_param=text)--*/
virtual bool OnTooltip(CefRefPtr<CefBrowser> browser, virtual bool OnTooltip(CefRefPtr<CefBrowser> browser,

View File

@ -0,0 +1,123 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_RENDER_HANDLER_H_
#define CEF_INCLUDE_CEF_RENDER_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include <vector>
///
// Implement this interface to handle events when window rendering is disabled.
// The methods of this class will be called on the UI thread.
///
/*--cef(source=client)--*/
class CefRenderHandler : public virtual CefBase {
public:
typedef cef_paint_element_type_t PaintElementType;
typedef std::vector<CefRect> RectList;
///
// Called to retrieve the root window rectangle in screen coordinates. Return
// true if the rectangle was provided. Return false if the screen rectangle is
// the same as the view rectangle.
///
/*--cef()--*/
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) { return false; }
///
// Called to retrieve the view rectangle which is relative to screen
// coordinates. Return true if the rectangle was provided.
///
/*--cef()--*/
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) =0;
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true if the screen coordinates were provided.
///
/*--cef()--*/
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) { return false; }
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true and hidden if |show| is false.
// NOTE: Popup widgets are not yet supported.
///
/*--cef()--*/
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {}
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size.
// NOTE: Popup widgets are not yet supported.
///
/*--cef()--*/
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {}
///
// Called when an element should be painted. |type| indicates whether the
// element is the view or the popup widget. |buffer| contains the pixel data
// for the whole image. |dirtyRects| contains the set of rectangles that need
// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes
// in size and represents a BGRA image with an upper-left origin.
// NOTE: Popup widgets are not yet supported.
///
/*--cef()--*/
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) =0;
///
// Called when the browser window's cursor has changed.
///
/*--cef()--*/
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {}
};
#endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_

View File

@ -961,6 +961,23 @@ enum cef_menu_id_t {
MENU_ID_USER_LAST = 28500, MENU_ID_USER_LAST = 28500,
}; };
///
// Mouse button types.
///
enum cef_mouse_button_type_t {
MBT_LEFT = 0,
MBT_MIDDLE,
MBT_RIGHT,
};
///
// Paint element types.
///
enum cef_paint_element_type_t {
PET_VIEW = 0,
PET_POPUP,
};
/// ///
// Supported event bit flags. // Supported event bit flags.
/// ///

View File

@ -43,7 +43,7 @@ extern "C" {
#endif #endif
// Handle types. // Handle types.
#define cef_cursor_handle_t GtkCursor* #define cef_cursor_handle_t void*
#define cef_event_handle_t GdkEvent* #define cef_event_handle_t GdkEvent*
#define cef_window_handle_t GtkWidget* #define cef_window_handle_t GtkWidget*

View File

@ -69,6 +69,12 @@ typedef struct _cef_window_info_t {
cef_window_handle_t parent_window; cef_window_handle_t parent_window;
HMENU menu; HMENU menu;
// If window rendering is disabled no browser window will be created. Set
// |parent_window| to be used for identifying monitor info
// (MonitorFromWindow). If |parent_window| is not provided the main screen
// monitor will be used.
BOOL window_rendering_disabled;
// Set to true to enable transparent painting. // Set to true to enable transparent painting.
BOOL transparent_painting; BOOL transparent_painting;

View File

@ -120,6 +120,7 @@ struct CefWindowInfoTraits {
target->menu = src->menu; target->menu = src->menu;
target->window = src->window; target->window = src->window;
target->transparent_painting = src->transparent_painting; target->transparent_painting = src->transparent_painting;
target->window_rendering_disabled = src->window_rendering_disabled;
} }
}; };
@ -159,6 +160,11 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
void SetTransparentPainting(BOOL transparentPainting) { void SetTransparentPainting(BOOL transparentPainting) {
transparent_painting = transparentPainting; transparent_painting = transparentPainting;
} }
void SetAsOffScreen(HWND hWndParent) {
window_rendering_disabled = TRUE;
parent_window = hWndParent;
}
}; };
#endif // OS_WIN #endif // OS_WIN

View File

@ -0,0 +1,25 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/backing_store_osr.h"
#include "ui/gfx/rect.h"
BackingStoreOSR::BackingStoreOSR(content::RenderWidgetHost* widget,
const gfx::Size& size)
: content::BackingStore(widget, size) {
bitmap_.Allocate(size.width(), size.height(), true);
}
void BackingStoreOSR::ScrollBackingStore(const gfx::Vector2d& delta,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
SkIRect subset_rect = SkIRect::MakeXYWH(clip_rect.x(), clip_rect.y(),
clip_rect.width(), clip_rect.height());
bitmap_.GetBitmap().scrollRect(&subset_rect, delta.x(), delta.y());
}
const void* BackingStoreOSR::getPixels() const {
return const_cast<BackingStoreOSR*>(this)->bitmap_.GetBitmap().getPixels();
}

View File

@ -0,0 +1,51 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_BACKING_STORE_OSR_H_
#define CEF_LIBCEF_BROWSER_BACKING_STORE_OSR_H_
#include <vector>
#include "content/browser/renderer_host/backing_store.h"
#include "ui/gfx/canvas.h"
class CefRenderWidgetHostViewOSR;
class BackingStoreOSR : public content::BackingStore {
public:
static BackingStoreOSR* From(content::BackingStore* backing_store) {
return static_cast<BackingStoreOSR*>(backing_store);
}
// BackingStore implementation.
virtual void PaintToBackingStore(
content::RenderProcessHost* process,
TransportDIB::Id bitmap,
const gfx::Rect& bitmap_rect,
const std::vector<gfx::Rect>& copy_rects,
float scale_factor,
const base::Closure& completion_callback,
bool* scheduled_completion_callback) OVERRIDE;
virtual bool CopyFromBackingStore(const gfx::Rect& rect,
skia::PlatformBitmap* output) OVERRIDE;
virtual void ScrollBackingStore(const gfx::Vector2d& delta,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) OVERRIDE;
const void* getPixels() const;
private:
// Can be instantiated only within CefRenderWidgetHostViewOSR.
friend class CefRenderWidgetHostViewOSR;
explicit BackingStoreOSR(content::RenderWidgetHost* widget,
const gfx::Size& size);
virtual ~BackingStoreOSR() {}
skia::PlatformBitmap bitmap_;
DISALLOW_COPY_AND_ASSIGN(BackingStoreOSR);
};
#endif // CEF_LIBCEF_BROWSER_BACKING_STORE_OSR_H_

View File

@ -0,0 +1,86 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/backing_store_osr.h"
#include "content/public/browser/render_process_host.h"
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/rect.h"
#include "ui/surface/transport_dib.h"
// Portions extracted from content/browser/renderer_host/backing_store_win.cc.
namespace {
void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h,
int src_x, int src_y, int src_w, int src_h, void* pixels,
const BITMAPINFO* bitmap_info) {
// When blitting a rectangle that touches the bottom left corner of the bitmap
// StretchDIBits looks at it top-down! For more details, see
// http://wiki.allegro.cc/index.php?title=StretchDIBits.
int rv;
int bitmap_h = -bitmap_info->bmiHeader.biHeight;
int bottom_up_src_y = bitmap_h - src_y - src_h;
if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) {
rv = StretchDIBits(hdc,
dest_x, dest_h + dest_y - 1, dest_w, -dest_h,
src_x, bitmap_h - src_y + 1, src_w, -src_h,
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
} else {
rv = StretchDIBits(hdc,
dest_x, dest_y, dest_w, dest_h,
src_x, bottom_up_src_y, src_w, src_h,
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
}
DCHECK(rv != GDI_ERROR);
}
} // namespace
void BackingStoreOSR::PaintToBackingStore(
content::RenderProcessHost* process,
TransportDIB::Id bitmap,
const gfx::Rect& bitmap_rect,
const std::vector<gfx::Rect>& copy_rects,
float scale_factor,
const base::Closure& completion_callback,
bool* scheduled_completion_callback) {
*scheduled_completion_callback = false;
TransportDIB* dib = process->GetTransportDIB(bitmap);
if (!dib)
return;
BITMAPINFOHEADER hdr;
gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr);
// Account for a bitmap_rect that exceeds the bounds of our view.
gfx::Rect view_rect(size());
HDC temp_dc = bitmap_.GetSurface();
for (size_t i = 0; i < copy_rects.size(); i++) {
gfx::Rect paint_rect(copy_rects[i]);
paint_rect.Intersect(view_rect);
CallStretchDIBits(temp_dc,
paint_rect.x(),
paint_rect.y(),
paint_rect.width(),
paint_rect.height(),
paint_rect.x() - bitmap_rect.x(),
paint_rect.y() - bitmap_rect.y(),
paint_rect.width(),
paint_rect.height(),
dib->memory(),
reinterpret_cast<BITMAPINFO*>(&hdr));
}
}
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
skia::PlatformBitmap* output) {
if (!output->Allocate(rect.width(), rect.height(), true))
return false;
HDC src_dc = bitmap_.GetSurface();
HDC dst_dc = output->GetSurface();
return BitBlt(dst_dc, 0, 0, rect.width(), rect.height(),
src_dc, rect.x(), rect.y(), SRCCOPY) ? true : false;
}

View File

@ -172,7 +172,8 @@ class CefSpeechRecognitionPreferences
} // namespace } // namespace
CefBrowserContext::CefBrowserContext() { CefBrowserContext::CefBrowserContext()
: use_osr_next_contents_view_(false) {
// Initialize the request context getter. // Initialize the request context getter.
url_request_getter_ = new CefURLRequestContextGetter( url_request_getter_ = new CefURLRequestContextGetter(
false, false,
@ -275,3 +276,11 @@ content::SpeechRecognitionPreferences*
quota::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() { quota::SpecialStoragePolicy* CefBrowserContext::GetSpecialStoragePolicy() {
return NULL; return NULL;
} }
bool CefBrowserContext::use_osr_next_contents_view() const {
return use_osr_next_contents_view_;
}
void CefBrowserContext::set_use_osr_next_contents_view(bool override) {
use_osr_next_contents_view_ = override;
}

View File

@ -49,6 +49,13 @@ class CefBrowserContext : public content::BrowserContext {
GetSpeechRecognitionPreferences() OVERRIDE; GetSpeechRecognitionPreferences() OVERRIDE;
virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE; virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
// To disable window rendering call this function with |override|=true
// just before calling WebContents::Create. This will cause
// CefContentBrowserClient::OverrideCreateWebContentsView to create
// a windowless WebContentsView object.
void set_use_osr_next_contents_view(bool override);
bool use_osr_next_contents_view() const;
private: private:
scoped_ptr<CefResourceContext> resource_context_; scoped_ptr<CefResourceContext> resource_context_;
@ -59,6 +66,8 @@ class CefBrowserContext : public content::BrowserContext {
scoped_refptr<content::SpeechRecognitionPreferences> scoped_refptr<content::SpeechRecognitionPreferences>
speech_recognition_preferences_; speech_recognition_preferences_;
bool use_osr_next_contents_view_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext); DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
}; };

View File

@ -38,6 +38,11 @@
#include "content/public/common/file_chooser_params.h" #include "content/public/common/file_chooser_params.h"
#include "ui/base/dialogs/selected_file_info.h" #include "ui/base/dialogs/selected_file_info.h"
#if defined(OS_WIN)
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/web_contents_view_osr.h"
#endif
namespace { namespace {
class CreateBrowserHelper { class CreateBrowserHelper {
@ -220,6 +225,13 @@ bool CefBrowserHost::CreateBrowser(const CefWindowInfo& windowInfo,
return false; return false;
} }
// Verify that render handler is in place for a windowless browser.
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo) &&
!client->GetRenderHandler().get()) {
NOTREACHED() << "CefRenderHandler implementation is required";
return false;
}
// Create the browser on the UI thread. // Create the browser on the UI thread.
CreateBrowserHelper* helper = CreateBrowserHelper* helper =
new CreateBrowserHelper(windowInfo, client, url, settings); new CreateBrowserHelper(windowInfo, client, url, settings);
@ -252,6 +264,15 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
return NULL; return NULL;
} }
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo) &&
!client->GetRenderHandler().get()) {
NOTREACHED() << "CefRenderHandler implementation is required";
return NULL;
}
_Context->browser_context()->set_use_osr_next_contents_view(
CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo));
int browser_id = _Context->GetNextBrowserID(); int browser_id = _Context->GetNextBrowserID();
CefRefPtr<CefBrowserHostImpl> browser = CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::Create(windowInfo, settings, client, NULL, browser_id, CefBrowserHostImpl::Create(windowInfo, settings, client, NULL, browser_id,
@ -286,8 +307,22 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
CefRefPtr<CefBrowserHostImpl> browser = CefRefPtr<CefBrowserHostImpl> browser =
new CefBrowserHostImpl(window_info, settings, client, web_contents, new CefBrowserHostImpl(window_info, settings, client, web_contents,
browser_id, opener); browser_id, opener);
if (!browser->PlatformCreateWindow()) if (!browser->IsWindowRenderingDisabled() &&
!browser->PlatformCreateWindow()) {
return NULL; return NULL;
}
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
#if defined(OS_WIN)
if (browser->IsWindowRenderingDisabled()) {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents->GetRenderViewHost()->GetView());
if (view)
view->set_browser_impl(browser);
}
#endif // OS_WIN
_Context->AddBrowser(browser); _Context->AddBrowser(browser);
@ -397,10 +432,17 @@ CefRefPtr<CefBrowser> CefBrowserHostImpl::GetBrowser() {
void CefBrowserHostImpl::CloseBrowser() { void CefBrowserHostImpl::CloseBrowser() {
if (CEF_CURRENTLY_ON_UIT()) { if (CEF_CURRENTLY_ON_UIT()) {
PlatformCloseWindow(); if (IsWindowRenderingDisabled()) {
if (AllowDestroyBrowser()) {
ParentWindowWillClose();
DestroyBrowser();
}
} else {
PlatformCloseWindow();
}
} else { } else {
CEF_POST_TASK(CEF_UIT, CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::PlatformCloseWindow, this)); base::Bind(&CefBrowserHostImpl::CloseBrowser, this));
} }
} }
@ -491,6 +533,177 @@ void CefBrowserHostImpl::RunFileDialog(
base::Bind(&CefRunFileDialogCallbackWrapper::Callback, wrapper)); base::Bind(&CefRunFileDialogCallbackWrapper::Callback, wrapper));
} }
bool CefBrowserHostImpl::IsWindowRenderingDisabled() {
return IsWindowRenderingDisabled(window_info_);
}
void CefBrowserHostImpl::WasResized() {
if (!IsWindowRenderingDisabled()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::Bind(&CefBrowserHostImpl::WasResized, this));
return;
}
if (!web_contents())
return;
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (widget)
widget->WasResized();
}
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect) {
if (!IsWindowRenderingDisabled()) {
NOTREACHED() << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::Invalidate, this, dirtyRect));
return;
}
if (!web_contents())
return;
#if defined(OS_WIN)
content::RenderWidgetHostView* view =
web_contents()->GetRenderViewHost()->GetView();
CefRenderWidgetHostViewOSR* orview =
static_cast<CefRenderWidgetHostViewOSR*>(view);
if (orview) {
gfx::Rect rect(dirtyRect.x, dirtyRect.y,
dirtyRect.width, dirtyRect.height);
orview->Invalidate(rect);
}
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendKeyEvent, this, event));
return;
}
if (!web_contents())
return;
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (!widget)
return;
gfx::NativeEvent native_event;
if (PlatformTranslateKeyEvent(native_event, event))
widget->ForwardKeyboardEvent(content::NativeWebKeyboardEvent(native_event));
}
void CefBrowserHostImpl::SendMouseClickEvent(int x, int y,
MouseButtonType type, bool mouseUp, int clickCount) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendMouseClickEvent, this, x, y, type,
mouseUp, clickCount));
return;
}
if (!web_contents())
return;
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (!widget)
return;
WebKit::WebMouseEvent event;
if (PlatformTranslateClickEvent(event, x, y, type, mouseUp, clickCount))
widget->ForwardMouseEvent(event);
}
void CefBrowserHostImpl::SendMouseMoveEvent(int x, int y, bool mouseLeave) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendMouseMoveEvent, this, x, y,
mouseLeave));
return;
}
if (!web_contents())
return;
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (!widget)
return;
WebKit::WebMouseEvent event;
if (PlatformTranslateMoveEvent(event, x, y, mouseLeave))
widget->ForwardMouseEvent(event);
}
void CefBrowserHostImpl::SendMouseWheelEvent(int x, int y,
int deltaX, int deltaY) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendMouseWheelEvent, this, x, y,
deltaX, deltaY));
return;
}
if (!web_contents())
return;
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
if (!widget)
return;
WebKit::WebMouseWheelEvent event;
if (PlatformTranslateWheelEvent(event, x, y, deltaX, deltaY))
widget->ForwardWheelEvent(event);
}
void CefBrowserHostImpl::SendFocusEvent(bool setFocus) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendFocusEvent, this, setFocus));
return;
}
if (!web_contents())
return;
content::RenderWidgetHostImpl* widget =
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
if (!widget)
return;
if (setFocus) {
widget->GotFocus();
widget->SetActive(true);
} else {
widget->SetActive(false);
widget->Blur();
}
}
void CefBrowserHostImpl::SendCaptureLostEvent() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::SendCaptureLostEvent, this));
return;
}
if (!web_contents())
return;
content::RenderWidgetHostImpl* widget =
content::RenderWidgetHostImpl::From(web_contents()->GetRenderViewHost());
if (!widget)
return;
widget->LostCapture();
}
// CefBrowser methods. // CefBrowser methods.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -673,6 +886,19 @@ bool CefBrowserHostImpl::SendProcessMessage(
// CefBrowserHostImpl public methods. // CefBrowserHostImpl public methods.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool CefBrowserHostImpl::AllowDestroyBrowser() {
if (client_.get()) {
CefRefPtr<CefLifeSpanHandler> handler =
client_->GetLifeSpanHandler();
if (handler.get()) {
// Give the client a chance to handle this one.
return !handler->DoClose(this);
}
}
return true;
}
void CefBrowserHostImpl::DestroyBrowser() { void CefBrowserHostImpl::DestroyBrowser() {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
@ -1204,6 +1430,15 @@ bool CefBrowserHostImpl::ShouldCreateWebContents(
} }
} }
if (IsWindowRenderingDisabled(pending_window_info_) &&
!pending_client_->GetRenderHandler().get()) {
NOTREACHED() << "CefRenderHandler implementation is required";
return false;
}
_Context->browser_context()->set_use_osr_next_contents_view(
IsWindowRenderingDisabled(pending_window_info_));
return true; return true;
} }

View File

@ -34,6 +34,11 @@ namespace content {
struct NativeWebKeyboardEvent; struct NativeWebKeyboardEvent;
} }
namespace WebKit {
class WebMouseEvent;
class WebMouseWheelEvent;
}
namespace net { namespace net {
class URLRequest; class URLRequest;
} }
@ -97,6 +102,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
static CefRefPtr<CefBrowserHostImpl> GetBrowserByChildID( static CefRefPtr<CefBrowserHostImpl> GetBrowserByChildID(
int render_process_id); int render_process_id);
// Returns true if window rendering is disabled in CefWindowInfo.
static bool IsWindowRenderingDisabled(const CefWindowInfo& info);
// CefBrowserHost methods. // CefBrowserHost methods.
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE; virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void CloseBrowser() OVERRIDE; virtual void CloseBrowser() OVERRIDE;
@ -114,6 +122,17 @@ class CefBrowserHostImpl : public CefBrowserHost,
const CefString& default_file_name, const CefString& default_file_name,
const std::vector<CefString>& accept_types, const std::vector<CefString>& accept_types,
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE; CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
virtual bool IsWindowRenderingDisabled() OVERRIDE;
virtual void WasResized() OVERRIDE;
virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE;
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
virtual void SendMouseClickEvent(int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) OVERRIDE;
virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE;
virtual void SendMouseWheelEvent(int x, int y,
int deltaX, int deltaY) OVERRIDE;
virtual void SendFocusEvent(bool setFocus) OVERRIDE;
virtual void SendCaptureLostEvent() OVERRIDE;
// CefBrowser methods. // CefBrowser methods.
virtual CefRefPtr<CefBrowserHost> GetHost() OVERRIDE; virtual CefRefPtr<CefBrowserHost> GetHost() OVERRIDE;
@ -139,6 +158,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefProcessId target_process, CefProcessId target_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE; CefRefPtr<CefProcessMessage> message) OVERRIDE;
// Call LifeSpanHandler before destroying. Returns true if destruction
// is allowed at this time.
bool AllowDestroyBrowser();
// Destroy the browser members. This method should only be called after the // Destroy the browser members. This method should only be called after the
// native browser window is not longer processing messages. // native browser window is not longer processing messages.
void DestroyBrowser(); void DestroyBrowser();
@ -368,6 +392,17 @@ class CefBrowserHostImpl : public CefBrowserHost,
void PlatformRunFileChooser(const content::FileChooserParams& params, void PlatformRunFileChooser(const content::FileChooserParams& params,
RunFileChooserCallback callback); RunFileChooserCallback callback);
static bool PlatformTranslateKeyEvent(gfx::NativeEvent& native_event,
const CefKeyEvent& key_event);
static bool PlatformTranslateClickEvent(WebKit::WebMouseEvent& ev,
int x, int y, MouseButtonType type,
bool mouseUp, int clickCount);
static bool PlatformTranslateMoveEvent(WebKit::WebMouseEvent& ev,
int x, int y, bool mouseLeave);
static bool PlatformTranslateWheelEvent(WebKit::WebMouseWheelEvent& ev,
int x, int y,
int deltaX, int deltaY);
void OnAddressChange(CefRefPtr<CefFrame> frame, void OnAddressChange(CefRefPtr<CefFrame> frame,
const GURL& url); const GURL& url);
void OnLoadStart(CefRefPtr<CefFrame> frame, void OnLoadStart(CefRefPtr<CefFrame> frame,

View File

@ -333,3 +333,45 @@ void CefBrowserHostImpl::PlatformRunFileChooser(
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) { void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
} }
//static
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
// TODO(port): Implement this method as part of off-screen rendering support.
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
gfx::NativeEvent& native_event, const CefKeyEvent& event) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
WebKit::WebMouseEvent& ev,
int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
WebKit::WebMouseEvent& ev,
int x, int y, bool mouseLeave) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
WebKit::WebMouseWheelEvent& ev,
int x, int y, int deltaX, int deltaY) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}

View File

@ -318,3 +318,45 @@ void CefBrowserHostImpl::PlatformRunFileChooser(
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) { void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
} }
//static
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
// TODO(port): Implement this method as part of off-screen rendering support.
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
gfx::NativeEvent& native_event, const CefKeyEvent& event) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
WebKit::WebMouseEvent& ev,
int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
WebKit::WebMouseEvent& ev,
int x, int y, bool mouseLeave) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
WebKit::WebMouseWheelEvent& ev,
int x, int y, int deltaX, int deltaY) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
return false;
}

View File

@ -24,6 +24,8 @@
#include "grit/cef_strings.h" #include "grit/cef_strings.h"
#include "grit/ui_strings.h" #include "grit/ui_strings.h"
#include "net/base/mime_util.h" #include "net/base/mime_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/win/WebInputEventFactory.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/win/hwnd_util.h" #include "ui/base/win/hwnd_util.h"
@ -408,6 +410,23 @@ bool HasExternalHandler(const std::string& scheme) {
return false; return false;
} }
WORD KeyStatesToWord() {
static const USHORT kHighBitMaskShort = 0x8000;
WORD result = 0;
if (GetKeyState(VK_CONTROL) & kHighBitMaskShort)
result |= MK_CONTROL;
if (GetKeyState(VK_SHIFT) & kHighBitMaskShort)
result |= MK_SHIFT;
if (GetKeyState(VK_LBUTTON) & kHighBitMaskShort)
result |= MK_LBUTTON;
if (GetKeyState(VK_MBUTTON) & kHighBitMaskShort)
result |= MK_MBUTTON;
if (GetKeyState(VK_RBUTTON) & kHighBitMaskShort)
result |= MK_RBUTTON;
return result;
}
} // namespace } // namespace
// static // static
@ -575,7 +594,9 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
} }
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() { CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window; return IsWindowRenderingDisabled() ?
window_info_.parent_window :
window_info_.window;
} }
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) { bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
@ -660,3 +681,103 @@ void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
url)); url));
} }
} }
// static
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
return info.window_rendering_disabled ? true : false;
}
// static
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
gfx::NativeEvent& native_event, const CefKeyEvent& key_event) {
UINT message = 0;
WPARAM wparam = key_event.windows_key_code;
LPARAM lparam = key_event.native_key_code;
switch (key_event.type) {
case KEYEVENT_KEYUP:
message = key_event.is_system_key ? WM_SYSKEYUP : WM_KEYUP;
break;
case KEYEVENT_RAWKEYDOWN:
case KEYEVENT_KEYDOWN:
message = key_event.is_system_key ? WM_SYSKEYDOWN : WM_KEYDOWN;
break;
case KEYEVENT_CHAR:
message = key_event.is_system_key ? WM_SYSCHAR : WM_CHAR;
break;
default:
return false;
}
gfx::NativeEvent ev = {NULL, message, wparam, lparam};
native_event = ev;
return true;
}
// static
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
WebKit::WebMouseEvent& ev,
int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) {
DCHECK(clickCount >=1 && clickCount <= 2);
UINT message = 0;
WPARAM wparam = KeyStatesToWord();
LPARAM lparam = MAKELPARAM(x, y);
if (type == MBT_LEFT) {
if (mouseUp)
message = (clickCount == 1 ? WM_LBUTTONUP : WM_LBUTTONDBLCLK);
else
message = WM_LBUTTONDOWN;
} else if (type == MBT_MIDDLE) {
if (mouseUp)
message = (clickCount == 1 ? WM_MBUTTONUP : WM_MBUTTONDBLCLK);
else
message = WM_MBUTTONDOWN;
} else if (type == MBT_RIGHT) {
if (mouseUp)
message = (clickCount == 1 ? WM_RBUTTONUP : WM_RBUTTONDBLCLK);
else
message = WM_RBUTTONDOWN;
}
if (message == 0) {
NOTREACHED();
return false;
}
ev = WebKit::WebInputEventFactory::mouseEvent(NULL, message, wparam, lparam);
return true;
}
// static
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
WebKit::WebMouseEvent& ev,
int x, int y, bool mouseLeave) {
UINT message;
WPARAM wparam = KeyStatesToWord();
LPARAM lparam = 0;
if (mouseLeave) {
message = WM_MOUSELEAVE;
} else {
message = WM_MOUSEMOVE;
lparam = MAKELPARAM(x, y);
}
ev = WebKit::WebInputEventFactory::mouseEvent(NULL, message, wparam, lparam);
return true;
}
// static
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
WebKit::WebMouseWheelEvent& ev,
int x, int y, int deltaX, int deltaY) {
WPARAM wparam = MAKEWPARAM(KeyStatesToWord(), deltaY);
LPARAM lparam = MAKELPARAM(x, y);
ev = WebKit::WebInputEventFactory::mouseWheelEvent(NULL, WM_MOUSEWHEEL,
wparam, lparam);
return true;
}

View File

@ -34,6 +34,10 @@
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#if defined(OS_WIN)
#include "libcef/browser/web_contents_view_osr.h"
#endif
namespace { namespace {
// In-memory store for access tokens used by geolocation. // In-memory store for access tokens used by geolocation.
@ -291,6 +295,29 @@ content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
return browser_main_parts_; return browser_main_parts_;
} }
content::WebContentsView*
CefContentBrowserClient::OverrideCreateWebContentsView(
content::WebContents* web_contents,
content::RenderViewHostDelegateView** render_view_host_delegate_view) {
content::WebContentsView* view = NULL;
*render_view_host_delegate_view = NULL;
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
#if defined(OS_WIN)
CefBrowserContext* browserContext =
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
if (browserContext && browserContext->use_osr_next_contents_view()) {
CefWebContentsViewOSR* view_or = new CefWebContentsViewOSR(web_contents,
GetWebContentsViewDelegate(web_contents));
*render_view_host_delegate_view = view_or;
view = view_or;
}
#endif // OS_WIN
return view;
}
void CefContentBrowserClient::RenderProcessHostCreated( void CefContentBrowserClient::RenderProcessHostCreated(
content::RenderProcessHost* host) { content::RenderProcessHost* host) {
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host)); host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host));

View File

@ -57,6 +57,9 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const content::MainFunctionParams& parameters) OVERRIDE; const content::MainFunctionParams& parameters) OVERRIDE;
virtual void RenderProcessHostCreated( virtual void RenderProcessHostCreated(
content::RenderProcessHost* host) OVERRIDE; content::RenderProcessHost* host) OVERRIDE;
virtual content::WebContentsView* OverrideCreateWebContentsView(
content::WebContents* web_contents,
content::RenderViewHostDelegateView** rvhdv) OVERRIDE;
virtual void AppendExtraCommandLineSwitches(CommandLine* command_line, virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
int child_process_id) OVERRIDE; int child_process_id) OVERRIDE;
virtual content::QuotaPermissionContext* virtual content::QuotaPermissionContext*
@ -70,6 +73,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
virtual void BrowserURLHandlerCreated( virtual void BrowserURLHandlerCreated(
content::BrowserURLHandler* handler) OVERRIDE; content::BrowserURLHandler* handler) OVERRIDE;
virtual std::string GetDefaultDownloadName() OVERRIDE; virtual std::string GetDefaultDownloadName() OVERRIDE;
#if defined(OS_WIN) #if defined(OS_WIN)
const wchar_t* GetResourceDllName() OVERRIDE; const wchar_t* GetResourceDllName() OVERRIDE;
#endif #endif

View File

@ -21,11 +21,32 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) {
// Make sure events can be pumped while the menu is up. // Make sure events can be pumped while the menu is up.
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
gfx::Point screen_point(manager->params().x, manager->params().y); gfx::Point screen_point;
POINT temp = screen_point.ToPOINT();
HWND hwnd = manager->browser()->GetWebContents()->GetView()->GetNativeView(); if (manager->browser()->IsWindowRenderingDisabled()) {
ClientToScreen(hwnd, &temp); CefRefPtr<CefClient> client = manager->browser()->GetClient();
screen_point = temp; if (!client.get())
return false;
CefRefPtr<CefRenderHandler> handler = client->GetRenderHandler();
if (!handler.get())
return false;
int screenX = 0, screenY = 0;
if (!handler->GetScreenPoint(manager->browser(),
manager->params().x, manager->params().y,
screenX, screenY)) {
return false;
}
screen_point = gfx::Point(screenX, screenY);
} else {
POINT temp = {manager->params().x, manager->params().y};
HWND hwnd =
manager->browser()->GetWebContents()->GetView()->GetNativeView();
ClientToScreen(hwnd, &temp);
screen_point = temp;
}
// Show the menu. Blocks until the menu is dismissed. // Show the menu. Blocks until the menu is dismissed.
menu_->RunMenuAt(screen_point, views::Menu2::ALIGN_TOPLEFT); menu_->RunMenuAt(screen_point, views::Menu2::ALIGN_TOPLEFT);

View File

@ -0,0 +1,339 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/backing_store_osr.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/render_widget_host_view_osr.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_client.h"
#include "webkit/glue/webcursor.h"
///////////////////////////////////////////////////////////////////////////////
// CefRenderWidgetHostViewOSR, public:
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
content::RenderWidgetHost* widget)
: render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
about_to_validate_and_paint_(false) {
DCHECK(render_widget_host_);
render_widget_host_->SetView(this);
// CefBrowserHostImpl might not be created at this time for popups.
browser_impl_ = CefBrowserHostImpl::GetBrowserForHost(
content::RenderViewHost::From(render_widget_host_));
}
CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
}
// RenderWidgetHostView implementation.
void CefRenderWidgetHostViewOSR::InitAsChild(gfx::NativeView parent_view) {
}
content::RenderWidgetHost*
CefRenderWidgetHostViewOSR::GetRenderWidgetHost() const {
return render_widget_host_;
}
void CefRenderWidgetHostViewOSR::SetSize(const gfx::Size& size) {
}
void CefRenderWidgetHostViewOSR::SetBounds(const gfx::Rect& rect) {
}
gfx::NativeView CefRenderWidgetHostViewOSR::GetNativeView() const {
return gfx::NativeView();
}
gfx::NativeViewId CefRenderWidgetHostViewOSR::GetNativeViewId() const {
if (!browser_impl_.get())
return gfx::NativeViewId();
// This Id is used on Windows as HWND to retrieve monitor info
// If this Id is not a valid window, the main screen monitor info is used
return reinterpret_cast<gfx::NativeViewId>(browser_impl_->GetWindowHandle());
}
gfx::NativeViewAccessible
CefRenderWidgetHostViewOSR::GetNativeViewAccessible() {
return gfx::NativeViewAccessible();
}
bool CefRenderWidgetHostViewOSR::HasFocus() const {
return false;
}
bool CefRenderWidgetHostViewOSR::IsSurfaceAvailableForCopy() const {
return false;
}
void CefRenderWidgetHostViewOSR::Show() {
WasShown();
}
void CefRenderWidgetHostViewOSR::Hide() {
WasHidden();
}
bool CefRenderWidgetHostViewOSR::IsShowing() {
return true;
}
gfx::Rect CefRenderWidgetHostViewOSR::GetViewBounds() const {
if (!browser_impl_.get())
return gfx::Rect();
CefRect rc;
browser_impl_->GetClient()->GetRenderHandler()->GetViewRect(
browser_impl_->GetBrowser(), rc);
return gfx::Rect(rc.x, rc.y, rc.width, rc.height);
}
// Implementation of RenderWidgetHostViewPort.
void CefRenderWidgetHostViewOSR::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {
}
void CefRenderWidgetHostViewOSR::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
}
void CefRenderWidgetHostViewOSR::WasShown() {
if (render_widget_host_)
render_widget_host_->WasShown();
}
void CefRenderWidgetHostViewOSR::WasHidden() {
if (render_widget_host_)
render_widget_host_->WasHidden();
}
void CefRenderWidgetHostViewOSR::MovePluginWindows(
const gfx::Vector2d& scroll_offset,
const std::vector<webkit::npapi::WebPluginGeometry>& moves) {
}
void CefRenderWidgetHostViewOSR::Focus() {
}
void CefRenderWidgetHostViewOSR::Blur() {
}
void CefRenderWidgetHostViewOSR::UpdateCursor(const WebCursor& cursor) {
if (!browser_impl_.get())
return;
#if defined(OS_WIN)
HMODULE hModule = ::GetModuleHandle(
content::GetContentClient()->browser()->GetResourceDllName());
if (!hModule)
hModule = ::GetModuleHandle(NULL);
WebCursor web_cursor = cursor;
HCURSOR hCursor = web_cursor.GetCursor((HINSTANCE)hModule);
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
browser_impl_->GetBrowser(), hCursor);
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {
}
void CefRenderWidgetHostViewOSR::TextInputStateChanged(
const ViewHostMsg_TextInputState_Params& params) {
}
void CefRenderWidgetHostViewOSR::ImeCancelComposition() {
}
void CefRenderWidgetHostViewOSR::DidUpdateBackingStore(
const gfx::Rect& scroll_rect,
const gfx::Vector2d& scroll_delta,
const std::vector<gfx::Rect>& copy_rects) {
if (!scroll_rect.IsEmpty()) {
std::vector<gfx::Rect> dirty_rects(copy_rects);
dirty_rects.push_back(scroll_rect);
Paint(dirty_rects);
} else {
Paint(copy_rects);
}
}
void CefRenderWidgetHostViewOSR::RenderViewGone(
base::TerminationStatus status,
int error_code) {
render_widget_host_ = NULL;
}
#if defined(OS_WIN) && !defined(USE_AURA)
void CefRenderWidgetHostViewOSR::WillWmDestroy() {
// Will not be called if GetNativeView returns NULL.
NOTREACHED();
}
#endif
gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
if (!browser_impl_.get())
return gfx::Rect();
CefRect rc;
// If GetRootScreenRect is not implemented use the view rect as the root
// screen rect.
if (browser_impl_->GetClient()->GetRenderHandler()->GetRootScreenRect(
browser_impl_->GetBrowser(), rc) ||
browser_impl_->GetClient()->GetRenderHandler()->GetViewRect(
browser_impl_->GetBrowser(), rc)) {
return gfx::Rect(rc.x, rc.y, rc.width, rc.height);
}
return gfx::Rect();
}
void CefRenderWidgetHostViewOSR::Destroy() {
delete this;
}
void CefRenderWidgetHostViewOSR::SetTooltipText(const string16& tooltip_text) {
if (!browser_impl_.get())
return;
CefString tooltip(tooltip_text);
CefRefPtr<CefDisplayHandler> handler =
browser_impl_->GetClient()->GetDisplayHandler();
if (handler.get()) {
handler->OnTooltip(browser_impl_->GetBrowser(), tooltip);
}
}
content::BackingStore* CefRenderWidgetHostViewOSR::AllocBackingStore(
const gfx::Size& size) {
return new BackingStoreOSR(render_widget_host_, size);
}
void CefRenderWidgetHostViewOSR::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool)>& callback,
skia::PlatformBitmap* output) {
}
void CefRenderWidgetHostViewOSR::OnAcceleratedCompositingStateChange() {
}
void CefRenderWidgetHostViewOSR::SetHasHorizontalScrollbar(
bool has_horizontal_scrollbar) {
}
void CefRenderWidgetHostViewOSR::SetScrollOffsetPinning(
bool is_pinned_to_left, bool is_pinned_to_right) {
}
gfx::GLSurfaceHandle CefRenderWidgetHostViewOSR::GetCompositingSurface() {
return gfx::GLSurfaceHandle();
}
void CefRenderWidgetHostViewOSR::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
}
void CefRenderWidgetHostViewOSR::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
}
void CefRenderWidgetHostViewOSR::AcceleratedSurfaceSuspend() {
}
bool CefRenderWidgetHostViewOSR::HasAcceleratedSurface(
const gfx::Size& desired_size) {
return false;
}
bool CefRenderWidgetHostViewOSR::LockMouse() {
return false;
}
void CefRenderWidgetHostViewOSR::UnlockMouse() {
}
#if defined(OS_WIN) && !defined(USE_AURA)
void CefRenderWidgetHostViewOSR::SetClickthroughRegion(SkRegion* region) {
}
#endif
void CefRenderWidgetHostViewOSR::Invalidate(const gfx::Rect& rect) {
std::vector<gfx::Rect> dirtyRects;
dirtyRects.push_back(rect);
Paint(dirtyRects);
}
void CefRenderWidgetHostViewOSR::Paint(
const std::vector<gfx::Rect>& copy_rects) {
if (about_to_validate_and_paint_ ||
!browser_impl_.get() ||
!render_widget_host_) {
pending_update_rects_.insert(pending_update_rects_.end(),
copy_rects.begin(), copy_rects.end());
return;
}
about_to_validate_and_paint_ = true;
BackingStoreOSR* backing_store =
BackingStoreOSR::From(render_widget_host_->GetBackingStore(true));
about_to_validate_and_paint_ = false;
if (backing_store) {
const gfx::Rect client_rect(backing_store->size());
SkRegion damaged_rgn;
for (size_t i = 0; i < copy_rects.size(); ++i) {
SkIRect skRect = SkIRect::MakeLTRB(
copy_rects[i].x(), copy_rects[i].y(),
copy_rects[i].right(), copy_rects[i].bottom());
damaged_rgn.op(skRect, SkRegion::kUnion_Op);
}
for (size_t i = 0; i < pending_update_rects_.size(); ++i) {
SkIRect skRect = SkIRect::MakeLTRB(
pending_update_rects_[i].x(), pending_update_rects_[i].y(),
pending_update_rects_[i].right(), pending_update_rects_[i].bottom());
damaged_rgn.op(skRect, SkRegion::kUnion_Op);
}
pending_update_rects_.clear();
CefRenderHandler::RectList rcList;
SkRegion::Cliperator iterator(damaged_rgn,
SkIRect::MakeWH(client_rect.width(), client_rect.height()));
for (; !iterator.done(); iterator.next()) {
const SkIRect& r = iterator.rect();
rcList.push_back(
CefRect(r.left(), r.top(), r.width(), r.height()));
}
if (rcList.size() == 0)
return;
browser_impl_->GetClient()->GetRenderHandler()->OnPaint(
browser_impl_->GetBrowser(), PET_VIEW, rcList,
backing_store->getPixels(),
client_rect.width(), client_rect.height());
}
}
CefRefPtr<CefBrowserHostImpl>
CefRenderWidgetHostViewOSR::get_browser_impl() const {
return browser_impl_;
}
void CefRenderWidgetHostViewOSR::set_browser_impl(
CefRefPtr<CefBrowserHostImpl> browser) {
browser_impl_ = browser;
}

View File

@ -0,0 +1,142 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_
#define CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_
#pragma once
#include <vector>
#include "include/cef_base.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
namespace content {
class RenderWidgetHost;
class BackingStore;
}
class CefBrowserHostImpl;
class CefWebContentsViewOSR;
///////////////////////////////////////////////////////////////////////////////
// CefRenderWidgetHostViewOSR
//
// An object representing the "View" of a rendered web page. This object is
// responsible for sending paint events to the the CefRenderHandler
// when window rendering is disabled. It is the implementation of the
// RenderWidgetHostView that the cross-platform RenderWidgetHost object uses
// to display the data.
//
// Comment excerpted from render_widget_host.h:
//
// "The lifetime of the RenderWidgetHostHWND is tied to the render process.
// If the render process dies, the RenderWidgetHostHWND goes away and all
// references to it must become NULL."
//
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
///////////////////////////////////////////////////////////////////////////////
class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
public:
// RenderWidgetHostView methods.
virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
virtual content::RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual void SetBounds(const gfx::Rect& rect) OVERRIDE;
virtual gfx::NativeView GetNativeView() const OVERRIDE;
virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
virtual bool HasFocus() const OVERRIDE;
virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsShowing() OVERRIDE;
virtual gfx::Rect GetViewBounds() const OVERRIDE;
// RenderWidgetHostViewPort methods.
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) OVERRIDE;
virtual void InitAsFullscreen(
RenderWidgetHostView* reference_host_view) OVERRIDE;
virtual void WasShown() OVERRIDE;
virtual void WasHidden() OVERRIDE;
virtual void MovePluginWindows(
const gfx::Vector2d& scroll_offset,
const std::vector<webkit::npapi::WebPluginGeometry>& moves) OVERRIDE;
virtual void Focus() OVERRIDE;
virtual void Blur() OVERRIDE;
virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE;
virtual void SetIsLoading(bool is_loading) OVERRIDE;
virtual void TextInputStateChanged(
const ViewHostMsg_TextInputState_Params& params) OVERRIDE;
virtual void ImeCancelComposition() OVERRIDE;
virtual void DidUpdateBackingStore(
const gfx::Rect& scroll_rect,
const gfx::Vector2d& scroll_delta,
const std::vector<gfx::Rect>& copy_rects) OVERRIDE;
virtual void RenderViewGone(base::TerminationStatus status,
int error_code) OVERRIDE;
#if defined(OS_WIN) && !defined(USE_AURA)
virtual void WillWmDestroy() OVERRIDE;
#endif
virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
virtual content::BackingStore*
AllocBackingStore(const gfx::Size& size) OVERRIDE;
virtual void CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool)>& callback,
skia::PlatformBitmap* output) OVERRIDE;
virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
virtual void SetHasHorizontalScrollbar(
bool has_horizontal_scrollbar) OVERRIDE;
virtual void SetScrollOffsetPinning(
bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE;
virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
virtual void AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
virtual bool LockMouse() OVERRIDE;
virtual void UnlockMouse() OVERRIDE;
#if defined(OS_WIN) && !defined(USE_AURA)
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
#endif
// CefRenderWidgetHostViewOSR methods
void Invalidate(const gfx::Rect& rect);
void Paint(const std::vector<gfx::Rect>& copy_rects);
CefRefPtr<CefBrowserHostImpl> get_browser_impl() const;
void set_browser_impl(CefRefPtr<CefBrowserHostImpl> browser);
private:
friend class CefWebContentsViewOSR;
explicit CefRenderWidgetHostViewOSR(content::RenderWidgetHost* widget);
virtual ~CefRenderWidgetHostViewOSR();
// The associated Model. While |this| is being Destroyed,
// |render_widget_host_| is NULL and the Windows message loop is run one last
// time. Message handlers must check for a NULL |render_widget_host_|.
content::RenderWidgetHostImpl* render_widget_host_;
CefRefPtr<CefBrowserHostImpl> browser_impl_;
bool about_to_validate_and_paint_;
std::vector<gfx::Rect> pending_update_rects_;
DISALLOW_COPY_AND_ASSIGN(CefRenderWidgetHostViewOSR);
};
#endif // CEF_LIBCEF_BROWSER_RENDER_WIDGET_HOST_VIEW_OSR_H_

View File

@ -0,0 +1,112 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/web_contents_view_osr.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
CefWebContentsViewOSR::CefWebContentsViewOSR(
content::WebContents* web_contents,
content::WebContentsViewDelegate* delegate)
: web_contents_(web_contents),
view_(NULL) {
}
CefWebContentsViewOSR::~CefWebContentsViewOSR() {
}
// Overridden from WebContentsView:
void CefWebContentsViewOSR::CreateView(const gfx::Size& initial_size) {
}
content::RenderWidgetHostView* CefWebContentsViewOSR::CreateViewForWidget(
content::RenderWidgetHost* render_widget_host) {
if (render_widget_host->GetView())
return render_widget_host->GetView();
view_ = new CefRenderWidgetHostViewOSR(render_widget_host);
return view_;
}
gfx::NativeView CefWebContentsViewOSR::GetNativeView() const {
return gfx::NativeView();
}
gfx::NativeView CefWebContentsViewOSR::GetContentNativeView() const {
return gfx::NativeView();
}
gfx::NativeWindow CefWebContentsViewOSR::GetTopLevelNativeWindow() const {
return gfx::NativeWindow();
}
void CefWebContentsViewOSR::GetContainerBounds(gfx::Rect *out) const {
*out = GetViewBounds();
}
void CefWebContentsViewOSR::SetPageTitle(const string16& title) {
}
void CefWebContentsViewOSR::OnTabCrashed(base::TerminationStatus status,
int error_code) {
view_ = NULL;
}
void CefWebContentsViewOSR::SizeContents(const gfx::Size& size) {
}
void CefWebContentsViewOSR::RenderViewCreated(content::RenderViewHost* host) {
}
void CefWebContentsViewOSR::Focus() {
}
void CefWebContentsViewOSR::SetInitialFocus() {
}
void CefWebContentsViewOSR::StoreFocus() {
}
void CefWebContentsViewOSR::RestoreFocus() {
}
WebDropData* CefWebContentsViewOSR::GetDropData() const {
return NULL;
}
bool CefWebContentsViewOSR::IsEventTracking() const {
return false;
}
void CefWebContentsViewOSR::CloseTabAfterEventTracking() {
}
gfx::Rect CefWebContentsViewOSR::GetViewBounds() const {
return view_ ? view_->GetViewBounds() : gfx::Rect();
}
// RenderViewHostDelegateView methods.
void CefWebContentsViewOSR::StartDragging(const WebDropData& drop_data,
WebKit::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const content::DragEventSourceInfo& event_info) {
// Dragging is not supported when window rendering is disabled.
web_contents_->SystemDragEnded();
}
void CefWebContentsViewOSR::ShowPopupMenu(const gfx::Rect& bounds,
int item_height,
double item_font_size,
int selected_item,
const std::vector<WebMenuItem>& items,
bool right_aligned,
bool allow_multiple_selection) {
}

View File

@ -0,0 +1,73 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_
#define CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_
#include <vector>
#include "content/port/browser/render_view_host_delegate_view.h"
#include "content/public/browser/web_contents_view.h"
namespace content {
class WebContents;
class WebContentsViewDelegate;
}
class CefBrowserHostImpl;
class CefRenderWidgetHostViewOSR;
// An implementation of WebContentsView for off-screen rendering.
class CefWebContentsViewOSR : public content::WebContentsView,
public content::RenderViewHostDelegateView {
public:
CefWebContentsViewOSR(content::WebContents* web_contents,
content::WebContentsViewDelegate* delegate);
virtual ~CefWebContentsViewOSR();
// WebContentsView methods.
virtual void CreateView(const gfx::Size& initial_size) OVERRIDE;
virtual content::RenderWidgetHostView* CreateViewForWidget(
content::RenderWidgetHost* render_widget_host) OVERRIDE;
virtual gfx::NativeView GetNativeView() const OVERRIDE;
virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
virtual void GetContainerBounds(gfx::Rect *out) const OVERRIDE;
virtual void SetPageTitle(const string16& title) OVERRIDE;
virtual void OnTabCrashed(base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void SizeContents(const gfx::Size& size) OVERRIDE;
virtual void RenderViewCreated(content::RenderViewHost* host) OVERRIDE;
virtual void Focus() OVERRIDE;
virtual void SetInitialFocus() OVERRIDE;
virtual void StoreFocus() OVERRIDE;
virtual void RestoreFocus() OVERRIDE;
virtual WebDropData* GetDropData() const OVERRIDE;
virtual bool IsEventTracking() const OVERRIDE;
virtual void CloseTabAfterEventTracking() OVERRIDE;
virtual gfx::Rect GetViewBounds() const OVERRIDE;
// RenderViewHostDelegateView methods.
virtual void StartDragging(const WebDropData& drop_data,
WebKit::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const content::DragEventSourceInfo& event_info) OVERRIDE;
virtual void ShowPopupMenu(const gfx::Rect& bounds,
int item_height,
double item_font_size,
int selected_item,
const std::vector<WebMenuItem>& items,
bool right_aligned,
bool allow_multiple_selection) OVERRIDE;
private:
content::WebContents* web_contents_;
CefRenderWidgetHostViewOSR* view_;
DISALLOW_COPY_AND_ASSIGN(CefWebContentsViewOSR);
};
#endif // CEF_LIBCEF_BROWSER_WEB_CONTENTS_VIEW_OSR_H_

View File

@ -270,6 +270,148 @@ void CEF_CALLBACK browser_host_run_file_dialog(struct _cef_browser_host_t* self,
CefRunFileDialogCallbackCToCpp::Wrap(callback)); CefRunFileDialogCallbackCToCpp::Wrap(callback));
} }
int CEF_CALLBACK browser_host_is_window_rendering_disabled(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefBrowserHostCppToC::Get(self)->IsWindowRenderingDisabled();
// Return type: bool
return _retval;
}
void CEF_CALLBACK browser_host_was_resized(struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->WasResized();
}
void CEF_CALLBACK browser_host_invalidate(struct _cef_browser_host_t* self,
const cef_rect_t* dirtyRect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: dirtyRect; type: simple_byref_const
DCHECK(dirtyRect);
if (!dirtyRect)
return;
// Translate param: dirtyRect; type: simple_byref_const
CefRect dirtyRectVal = dirtyRect?*dirtyRect:CefRect();
// Execute
CefBrowserHostCppToC::Get(self)->Invalidate(
dirtyRectVal);
}
void CEF_CALLBACK browser_host_send_key_event(struct _cef_browser_host_t* self,
const struct _cef_key_event_t* event) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: event; type: struct_byref_const
DCHECK(event);
if (!event)
return;
// Translate param: event; type: struct_byref_const
CefKeyEvent eventObj;
if (event)
eventObj.Set(*event, false);
// Execute
CefBrowserHostCppToC::Get(self)->SendKeyEvent(
eventObj);
}
void CEF_CALLBACK browser_host_send_mouse_click_event(
struct _cef_browser_host_t* self, int x, int y,
enum cef_mouse_button_type_t type, int mouseUp, int clickCount) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SendMouseClickEvent(
x,
y,
type,
mouseUp?true:false,
clickCount);
}
void CEF_CALLBACK browser_host_send_mouse_move_event(
struct _cef_browser_host_t* self, int x, int y, int mouseLeave) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SendMouseMoveEvent(
x,
y,
mouseLeave?true:false);
}
void CEF_CALLBACK browser_host_send_mouse_wheel_event(
struct _cef_browser_host_t* self, int x, int y, int deltaX, int deltaY) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SendMouseWheelEvent(
x,
y,
deltaX,
deltaY);
}
void CEF_CALLBACK browser_host_send_focus_event(
struct _cef_browser_host_t* self, int setFocus) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SendFocusEvent(
setFocus?true:false);
}
void CEF_CALLBACK browser_host_send_capture_lost_event(
struct _cef_browser_host_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SendCaptureLostEvent();
}
// CONSTRUCTOR - Do not edit by hand. // CONSTRUCTOR - Do not edit by hand.
@ -288,6 +430,17 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
struct_.struct_.get_zoom_level = browser_host_get_zoom_level; struct_.struct_.get_zoom_level = browser_host_get_zoom_level;
struct_.struct_.set_zoom_level = browser_host_set_zoom_level; struct_.struct_.set_zoom_level = browser_host_set_zoom_level;
struct_.struct_.run_file_dialog = browser_host_run_file_dialog; struct_.struct_.run_file_dialog = browser_host_run_file_dialog;
struct_.struct_.is_window_rendering_disabled =
browser_host_is_window_rendering_disabled;
struct_.struct_.was_resized = browser_host_was_resized;
struct_.struct_.invalidate = browser_host_invalidate;
struct_.struct_.send_key_event = browser_host_send_key_event;
struct_.struct_.send_mouse_click_event = browser_host_send_mouse_click_event;
struct_.struct_.send_mouse_move_event = browser_host_send_mouse_move_event;
struct_.struct_.send_mouse_wheel_event = browser_host_send_mouse_wheel_event;
struct_.struct_.send_focus_event = browser_host_send_focus_event;
struct_.struct_.send_capture_lost_event =
browser_host_send_capture_lost_event;
} }
#ifndef NDEBUG #ifndef NDEBUG

View File

@ -21,6 +21,7 @@
#include "libcef_dll/cpptoc/keyboard_handler_cpptoc.h" #include "libcef_dll/cpptoc/keyboard_handler_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h" #include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h" #include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/cpptoc/request_handler_cpptoc.h" #include "libcef_dll/cpptoc/request_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h" #include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/process_message_ctocpp.h" #include "libcef_dll/ctocpp/process_message_ctocpp.h"
@ -188,6 +189,22 @@ struct _cef_load_handler_t* CEF_CALLBACK client_get_load_handler(
return CefLoadHandlerCppToC::Wrap(_retval); return CefLoadHandlerCppToC::Wrap(_retval);
} }
struct _cef_render_handler_t* CEF_CALLBACK client_get_render_handler(
struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefRenderHandler> _retval = CefClientCppToC::Get(
self)->GetRenderHandler();
// Return type: refptr_same
return CefRenderHandlerCppToC::Wrap(_retval);
}
struct _cef_request_handler_t* CEF_CALLBACK client_get_request_handler( struct _cef_request_handler_t* CEF_CALLBACK client_get_request_handler(
struct _cef_client_t* self) { struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -246,6 +263,7 @@ CefClientCppToC::CefClientCppToC(CefClient* cls)
struct_.struct_.get_keyboard_handler = client_get_keyboard_handler; struct_.struct_.get_keyboard_handler = client_get_keyboard_handler;
struct_.struct_.get_life_span_handler = client_get_life_span_handler; struct_.struct_.get_life_span_handler = client_get_life_span_handler;
struct_.struct_.get_load_handler = client_get_load_handler; struct_.struct_.get_load_handler = client_get_load_handler;
struct_.struct_.get_render_handler = client_get_render_handler;
struct_.struct_.get_request_handler = client_get_request_handler; struct_.struct_.get_request_handler = client_get_request_handler;
struct_.struct_.on_process_message_received = struct_.struct_.on_process_message_received =
client_on_process_message_received; client_on_process_message_received;

View File

@ -0,0 +1,252 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK render_handler_get_root_screen_rect(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: rect; type: simple_byref
DCHECK(rect);
if (!rect)
return 0;
// Translate param: rect; type: simple_byref
CefRect rectVal = rect?*rect:CefRect();
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetRootScreenRect(
CefBrowserCToCpp::Wrap(browser),
rectVal);
// Restore param: rect; type: simple_byref
if (rect)
*rect = rectVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK render_handler_get_view_rect(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: rect; type: simple_byref
DCHECK(rect);
if (!rect)
return 0;
// Translate param: rect; type: simple_byref
CefRect rectVal = rect?*rect:CefRect();
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetViewRect(
CefBrowserCToCpp::Wrap(browser),
rectVal);
// Restore param: rect; type: simple_byref
if (rect)
*rect = rectVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK render_handler_get_screen_point(
struct _cef_render_handler_t* self, cef_browser_t* browser, int viewX,
int viewY, int* screenX, int* screenY) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: screenX; type: simple_byref
DCHECK(screenX);
if (!screenX)
return 0;
// Verify param: screenY; type: simple_byref
DCHECK(screenY);
if (!screenY)
return 0;
// Translate param: screenX; type: simple_byref
int screenXVal = screenX?*screenX:0;
// Translate param: screenY; type: simple_byref
int screenYVal = screenY?*screenY:0;
// Execute
bool _retval = CefRenderHandlerCppToC::Get(self)->GetScreenPoint(
CefBrowserCToCpp::Wrap(browser),
viewX,
viewY,
screenXVal,
screenYVal);
// Restore param: screenX; type: simple_byref
if (screenX)
*screenX = screenXVal;
// Restore param: screenY; type: simple_byref
if (screenY)
*screenY = screenYVal;
// Return type: bool
return _retval;
}
void CEF_CALLBACK render_handler_on_popup_show(
struct _cef_render_handler_t* self, cef_browser_t* browser, int show) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnPopupShow(
CefBrowserCToCpp::Wrap(browser),
show?true:false);
}
void CEF_CALLBACK render_handler_on_popup_size(
struct _cef_render_handler_t* self, cef_browser_t* browser,
const cef_rect_t* rect) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: rect; type: simple_byref_const
DCHECK(rect);
if (!rect)
return;
// Translate param: rect; type: simple_byref_const
CefRect rectVal = rect?*rect:CefRect();
// Execute
CefRenderHandlerCppToC::Get(self)->OnPopupSize(
CefBrowserCToCpp::Wrap(browser),
rectVal);
}
void CEF_CALLBACK render_handler_on_paint(struct _cef_render_handler_t* self,
cef_browser_t* browser, enum cef_paint_element_type_t type,
size_t dirtyRectsCount, cef_rect_t const* dirtyRects, const void* buffer,
int width, int height) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Verify param: dirtyRects; type: simple_vec_byref_const
DCHECK(dirtyRectsCount == 0 || dirtyRects);
if (dirtyRectsCount > 0 && !dirtyRects)
return;
// Verify param: buffer; type: simple_byaddr
DCHECK(buffer);
if (!buffer)
return;
// Translate param: dirtyRects; type: simple_vec_byref_const
std::vector<CefRect > dirtyRectsList;
if (dirtyRectsCount > 0) {
for (size_t i = 0; i < dirtyRectsCount; ++i) {
dirtyRectsList.push_back(dirtyRects[i]);
}
}
// Execute
CefRenderHandlerCppToC::Get(self)->OnPaint(
CefBrowserCToCpp::Wrap(browser),
type,
dirtyRectsList,
buffer,
width,
height);
}
void CEF_CALLBACK render_handler_on_cursor_change(
struct _cef_render_handler_t* self, cef_browser_t* browser,
cef_cursor_handle_t cursor) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnCursorChange(
CefBrowserCToCpp::Wrap(browser),
cursor);
}
// CONSTRUCTOR - Do not edit by hand.
CefRenderHandlerCppToC::CefRenderHandlerCppToC(CefRenderHandler* cls)
: CefCppToC<CefRenderHandlerCppToC, CefRenderHandler, cef_render_handler_t>(
cls) {
struct_.struct_.get_root_screen_rect = render_handler_get_root_screen_rect;
struct_.struct_.get_view_rect = render_handler_get_view_rect;
struct_.struct_.get_screen_point = render_handler_get_screen_point;
struct_.struct_.on_popup_show = render_handler_on_popup_show;
struct_.struct_.on_popup_size = render_handler_on_popup_size;
struct_.struct_.on_paint = render_handler_on_paint;
struct_.struct_.on_cursor_change = render_handler_on_cursor_change;
}
#ifndef NDEBUG
template<> long CefCppToC<CefRenderHandlerCppToC, CefRenderHandler,
cef_render_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_render_handler.h"
#include "include/capi/cef_render_handler_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefRenderHandlerCppToC
: public CefCppToC<CefRenderHandlerCppToC, CefRenderHandler,
cef_render_handler_t> {
public:
explicit CefRenderHandlerCppToC(CefRenderHandler* cls);
virtual ~CefRenderHandlerCppToC() {}
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_RENDER_HANDLER_CPPTOC_H_

View File

@ -223,6 +223,116 @@ void CefBrowserHostCToCpp::RunFileDialog(FileDialogMode mode,
cef_string_list_free(accept_typesList); cef_string_list_free(accept_typesList);
} }
bool CefBrowserHostCToCpp::IsWindowRenderingDisabled() {
if (CEF_MEMBER_MISSING(struct_, is_window_rendering_disabled))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = struct_->is_window_rendering_disabled(struct_);
// Return type: bool
return _retval?true:false;
}
void CefBrowserHostCToCpp::WasResized() {
if (CEF_MEMBER_MISSING(struct_, was_resized))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->was_resized(struct_);
}
void CefBrowserHostCToCpp::Invalidate(const CefRect& dirtyRect) {
if (CEF_MEMBER_MISSING(struct_, invalidate))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->invalidate(struct_,
&dirtyRect);
}
void CefBrowserHostCToCpp::SendKeyEvent(const CefKeyEvent& event) {
if (CEF_MEMBER_MISSING(struct_, send_key_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_key_event(struct_,
&event);
}
void CefBrowserHostCToCpp::SendMouseClickEvent(int x, int y,
MouseButtonType type, bool mouseUp, int clickCount) {
if (CEF_MEMBER_MISSING(struct_, send_mouse_click_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_mouse_click_event(struct_,
x,
y,
type,
mouseUp,
clickCount);
}
void CefBrowserHostCToCpp::SendMouseMoveEvent(int x, int y, bool mouseLeave) {
if (CEF_MEMBER_MISSING(struct_, send_mouse_move_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_mouse_move_event(struct_,
x,
y,
mouseLeave);
}
void CefBrowserHostCToCpp::SendMouseWheelEvent(int x, int y, int deltaX,
int deltaY) {
if (CEF_MEMBER_MISSING(struct_, send_mouse_wheel_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_mouse_wheel_event(struct_,
x,
y,
deltaX,
deltaY);
}
void CefBrowserHostCToCpp::SendFocusEvent(bool setFocus) {
if (CEF_MEMBER_MISSING(struct_, send_focus_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_focus_event(struct_,
setFocus);
}
void CefBrowserHostCToCpp::SendCaptureLostEvent() {
if (CEF_MEMBER_MISSING(struct_, send_capture_lost_event))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->send_capture_lost_event(struct_);
}
#ifndef NDEBUG #ifndef NDEBUG
template<> long CefCToCpp<CefBrowserHostCToCpp, CefBrowserHost, template<> long CefCToCpp<CefBrowserHostCToCpp, CefBrowserHost,

View File

@ -51,6 +51,17 @@ class CefBrowserHostCToCpp
const CefString& default_file_name, const CefString& default_file_name,
const std::vector<CefString>& accept_types, const std::vector<CefString>& accept_types,
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE; CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
virtual bool IsWindowRenderingDisabled() OVERRIDE;
virtual void WasResized() OVERRIDE;
virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE;
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
virtual void SendMouseClickEvent(int x, int y, MouseButtonType type,
bool mouseUp, int clickCount) OVERRIDE;
virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE;
virtual void SendMouseWheelEvent(int x, int y, int deltaX,
int deltaY) OVERRIDE;
virtual void SendFocusEvent(bool setFocus) OVERRIDE;
virtual void SendCaptureLostEvent() OVERRIDE;
}; };
#endif // USING_CEF_SHARED #endif // USING_CEF_SHARED

View File

@ -23,6 +23,7 @@
#include "libcef_dll/ctocpp/keyboard_handler_ctocpp.h" #include "libcef_dll/ctocpp/keyboard_handler_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h" #include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h" #include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
#include "libcef_dll/ctocpp/request_handler_ctocpp.h" #include "libcef_dll/ctocpp/request_handler_ctocpp.h"
@ -160,6 +161,19 @@ CefRefPtr<CefLoadHandler> CefClientCToCpp::GetLoadHandler() {
return CefLoadHandlerCToCpp::Wrap(_retval); return CefLoadHandlerCToCpp::Wrap(_retval);
} }
CefRefPtr<CefRenderHandler> CefClientCToCpp::GetRenderHandler() {
if (CEF_MEMBER_MISSING(struct_, get_render_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_render_handler_t* _retval = struct_->get_render_handler(struct_);
// Return type: refptr_same
return CefRenderHandlerCToCpp::Wrap(_retval);
}
CefRefPtr<CefRequestHandler> CefClientCToCpp::GetRequestHandler() { CefRefPtr<CefRequestHandler> CefClientCToCpp::GetRequestHandler() {
if (CEF_MEMBER_MISSING(struct_, get_request_handler)) if (CEF_MEMBER_MISSING(struct_, get_request_handler))
return NULL; return NULL;

View File

@ -42,6 +42,7 @@ class CefClientCToCpp
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE; virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE;
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE; virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE; virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE;
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE; virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE;
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process, CefProcessId source_process,

View File

@ -0,0 +1,189 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
bool CefRenderHandlerCToCpp::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, get_root_screen_rect))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_root_screen_rect(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
// Return type: bool
return _retval?true:false;
}
bool CefRenderHandlerCToCpp::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, get_view_rect))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_view_rect(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
// Return type: bool
return _retval?true:false;
}
bool CefRenderHandlerCToCpp::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX, int viewY, int& screenX, int& screenY) {
if (CEF_MEMBER_MISSING(struct_, get_screen_point))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Execute
int _retval = struct_->get_screen_point(struct_,
CefBrowserCppToC::Wrap(browser),
viewX,
viewY,
&screenX,
&screenY);
// Return type: bool
return _retval?true:false;
}
void CefRenderHandlerCToCpp::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (CEF_MEMBER_MISSING(struct_, on_popup_show))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_popup_show(struct_,
CefBrowserCppToC::Wrap(browser),
show);
}
void CefRenderHandlerCToCpp::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (CEF_MEMBER_MISSING(struct_, on_popup_size))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_popup_size(struct_,
CefBrowserCppToC::Wrap(browser),
&rect);
}
void CefRenderHandlerCToCpp::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type, const RectList& dirtyRects, const void* buffer,
int width, int height) {
if (CEF_MEMBER_MISSING(struct_, on_paint))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Verify param: buffer; type: simple_byaddr
DCHECK(buffer);
if (!buffer)
return;
// Translate param: dirtyRects; type: simple_vec_byref_const
const size_t dirtyRectsCount = dirtyRects.size();
cef_rect_t* dirtyRectsList = NULL;
if (dirtyRectsCount > 0) {
dirtyRectsList = new cef_rect_t[dirtyRectsCount];
DCHECK(dirtyRectsList);
if (dirtyRectsList) {
for (size_t i = 0; i < dirtyRectsCount; ++i) {
dirtyRectsList[i] = dirtyRects[i];
}
}
}
// Execute
struct_->on_paint(struct_,
CefBrowserCppToC::Wrap(browser),
type,
dirtyRectsCount,
dirtyRectsList,
buffer,
width,
height);
// Restore param:dirtyRects; type: simple_vec_byref_const
if (dirtyRectsList)
delete [] dirtyRectsList;
}
void CefRenderHandlerCToCpp::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (CEF_MEMBER_MISSING(struct_, on_cursor_change))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
struct_->on_cursor_change(struct_,
CefBrowserCppToC::Wrap(browser),
cursor);
}
#ifndef NDEBUG
template<> long CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,55 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_render_handler.h"
#include "include/capi/cef_render_handler_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefRenderHandlerCToCpp
: public CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t> {
public:
explicit CefRenderHandlerCToCpp(cef_render_handler_t* str)
: CefCToCpp<CefRenderHandlerCToCpp, CefRenderHandler,
cef_render_handler_t>(str) {}
virtual ~CefRenderHandlerCToCpp() {}
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser, int viewX,
int viewY, int& screenX, int& screenY) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList& dirtyRects, const void* buffer, int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_

View File

@ -85,6 +85,7 @@
#include "libcef_dll/ctocpp/load_handler_ctocpp.h" #include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/proxy_handler_ctocpp.h" #include "libcef_dll/ctocpp/proxy_handler_ctocpp.h"
#include "libcef_dll/ctocpp/read_handler_ctocpp.h" #include "libcef_dll/ctocpp/read_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_process_handler_ctocpp.h" #include "libcef_dll/ctocpp/render_process_handler_ctocpp.h"
#include "libcef_dll/ctocpp/request_handler_ctocpp.h" #include "libcef_dll/ctocpp/request_handler_ctocpp.h"
#include "libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h" #include "libcef_dll/ctocpp/resource_bundle_handler_ctocpp.h"
@ -208,6 +209,7 @@ CEF_EXPORT void cef_shutdown() {
DCHECK_EQ(CefProxyHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefProxyHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefQuotaCallbackCppToC::DebugObjCt, 0); DCHECK_EQ(CefQuotaCallbackCppToC::DebugObjCt, 0);
DCHECK_EQ(CefReadHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefReadHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRenderHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRenderProcessHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefRenderProcessHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefRequestHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefRequestHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefResourceBundleHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefResourceBundleHandlerCToCpp::DebugObjCt, 0);

View File

@ -51,6 +51,7 @@
#include "libcef_dll/cpptoc/load_handler_cpptoc.h" #include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/proxy_handler_cpptoc.h" #include "libcef_dll/cpptoc/proxy_handler_cpptoc.h"
#include "libcef_dll/cpptoc/read_handler_cpptoc.h" #include "libcef_dll/cpptoc/read_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_process_handler_cpptoc.h" #include "libcef_dll/cpptoc/render_process_handler_cpptoc.h"
#include "libcef_dll/cpptoc/request_handler_cpptoc.h" #include "libcef_dll/cpptoc/request_handler_cpptoc.h"
#include "libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h" #include "libcef_dll/cpptoc/resource_bundle_handler_cpptoc.h"
@ -200,6 +201,7 @@ CEF_GLOBAL void CefShutdown() {
DCHECK_EQ(CefProxyHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefProxyHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefQuotaCallbackCToCpp::DebugObjCt, 0); DCHECK_EQ(CefQuotaCallbackCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefReadHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefReadHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRenderHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRenderProcessHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefRenderProcessHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefRequestHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefRequestHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefResourceBundleHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefResourceBundleHandlerCppToC::DebugObjCt, 0);

View File

@ -104,6 +104,14 @@ void AppGetSettings(CefSettings& settings, CefRefPtr<ClientApp> app) {
} }
} }
bool AppIsOffScreenRenderingEnabled() {
ASSERT(g_command_line.get());
if (!g_command_line.get())
return false;
return g_command_line->HasSwitch(cefclient::kOffScreenRenderingEnabled);
}
// Returns the application browser settings based on command line arguments. // Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings) { void AppGetBrowserSettings(CefBrowserSettings& settings) {
ASSERT(g_command_line.get()); ASSERT(g_command_line.get());

View File

@ -35,6 +35,10 @@ void AppGetSettings(CefSettings& settings, CefRefPtr<ClientApp> app);
// Returns the application browser settings based on command line arguments. // Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings); void AppGetBrowserSettings(CefBrowserSettings& settings);
// Returns true if off-screen rendering is enabled via the command line
// argument.
bool AppIsOffScreenRenderingEnabled();
// Implementations for various tests. // Implementations for various tests.
void RunGetSourceTest(CefRefPtr<CefBrowser> browser); void RunGetSourceTest(CefRefPtr<CefBrowser> browser);
void RunGetTextTest(CefRefPtr<CefBrowser> browser); void RunGetTextTest(CefRefPtr<CefBrowser> browser);

View File

@ -157,6 +157,7 @@ STRINGTABLE
BEGIN BEGIN
IDS_APP_TITLE "cefclient" IDS_APP_TITLE "cefclient"
IDC_CEFCLIENT "CEFCLIENT" IDC_CEFCLIENT "CEFCLIENT"
IDS_OSR_WIDGET_CLASS "CEFCLIENT-OSR-WIDGET"
END END
#endif // English (U.S.) resources #endif // English (U.S.) resources

View File

@ -0,0 +1,361 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/cefclient_osr_widget_win.h"
#include "cefclient/resource.h"
#include "cefclient/util.h"
// static
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
bool transparent) {
ASSERT(browser_provider);
if (!browser_provider)
return NULL;
return new OSRWindow(browser_provider, transparent);
}
// static
CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<CefRenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get());
}
bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
HINSTANCE hInst, LPCTSTR className) {
ASSERT(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL);
Reset();
RegisterOSRClass(hInst, className);
hWnd_ = ::CreateWindow(className, 0,
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
hWndParent, 0, hInst, 0);
if (!hWnd_)
return false;
SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
AddRef();
// Enable GL drawing for the window.
EnableGL();
return true;
}
void OSRWindow::DestroyWidget() {
if (::IsWindow(hWnd_)) {
DisableGL();
DestroyWindow(hWnd_);
}
Reset();
}
bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
RECT window_rect = {0};
HWND root_window = GetAncestor(hWnd_, GA_ROOT);
if (::GetWindowRect(root_window, &window_rect)) {
rect = CefRect(window_rect.left,
window_rect.top,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top);
return true;
}
return false;
}
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
RECT clientRect;
if (!::GetClientRect(hWnd_, &clientRect))
return false;
rect.x = rect.y = 0;
rect.width = clientRect.right;
rect.height = clientRect.bottom;
return true;
}
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
if (!::IsWindow(hWnd_))
return false;
// Convert the point from view coordinates to actual screen coordinates.
POINT screen_pt = {viewX, viewY};
ClientToScreen(hWnd_, &screen_pt);
screenX = screen_pt.x;
screenY = screen_pt.y;
return true;
}
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
renderer_.OnPopupShow(browser, show);
}
void OSRWindow::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
renderer_.OnPopupSize(browser, rect);
}
void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) {
wglMakeCurrent(hDC_, hRC_);
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
renderer_.Render();
SwapBuffers(hDC_);
}
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (!::IsWindow(hWnd_))
return;
// Change the plugin window's cursor.
SetClassLong(hWnd_, GCL_HCURSOR,
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
SetCursor(cursor);
}
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
: renderer_(transparent),
browser_provider_(browser_provider) {
Reset();
}
OSRWindow::~OSRWindow() {
DestroyWidget();
}
void OSRWindow::EnableGL() {
PIXELFORMATDESCRIPTOR pfd;
int format;
// Get the device context.
hDC_ = GetDC(hWnd_);
// Set the pixel format for the DC.
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat(hDC_, &pfd);
SetPixelFormat(hDC_, format, &pfd);
// Create and enable the render context.
hRC_ = wglCreateContext(hDC_);
wglMakeCurrent(hDC_, hRC_);
renderer_.Initialize();
}
void OSRWindow::DisableGL() {
renderer_.Cleanup();
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC_);
ReleaseDC(hWnd_, hDC_);
}
void OSRWindow::Reset() {
hWnd_ = NULL;
hDC_ = NULL;
hRC_ = NULL;
}
ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = &OSRWindow::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = className;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
// Plugin window procedure.
// static
LRESULT CALLBACK OSRWindow::WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam) {
static POINT lastMousePos, curMousePos;
static bool mouseRotation = false;
static bool mouseTracking = false;
OSRWindow* window =
reinterpret_cast<OSRWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
CefRefPtr<CefBrowserHost> browser;
if (window && window->browser_provider_->GetBrowser().get())
browser = window->browser_provider_->GetBrowser()->GetHost();
switch (message) {
case WM_DESTROY:
if (window) {
SetWindowLongPtr(hWnd, GWLP_USERDATA, 0L);
window->Release();
}
return 0;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
SetCapture(hWnd);
SetFocus(hWnd);
if (wParam & MK_SHIFT) {
// Start rotation effect.
lastMousePos.x = curMousePos.x = LOWORD(lParam);
lastMousePos.y = curMousePos.y = HIWORD(lParam);
mouseRotation = true;
} else {
if (browser.get()) {
browser->SendMouseClickEvent(LOWORD(lParam), HIWORD(lParam),
(message == WM_LBUTTONDOWN?MBT_LEFT:MBT_RIGHT), false, 1);
}
}
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
if (GetCapture() == hWnd)
ReleaseCapture();
if (mouseRotation) {
// End rotation effect.
mouseRotation = false;
window->renderer_.SetSpin(0, 0);
} else {
if (browser.get()) {
browser->SendMouseClickEvent(LOWORD(lParam), HIWORD(lParam),
(message == WM_LBUTTONUP?MBT_LEFT:MBT_RIGHT), true, 1);
}
}
break;
case WM_MOUSEMOVE:
if (mouseRotation) {
// Apply rotation effect.
curMousePos.x = LOWORD(lParam);
curMousePos.y = HIWORD(lParam);
window->renderer_.IncrementSpin((curMousePos.x - lastMousePos.x),
(curMousePos.y - lastMousePos.y));
lastMousePos.x = curMousePos.x;
lastMousePos.y = curMousePos.y;
} else {
if (!mouseTracking) {
// Start tracking mouse leave. Required for the WM_MOUSELEAVE event to
// be generated.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
mouseTracking = true;
}
if (browser.get()) {
browser->SendMouseMoveEvent(LOWORD(lParam), HIWORD(lParam), false);
}
}
break;
case WM_MOUSELEAVE:
if (mouseTracking) {
// Stop tracking mouse leave.
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE & TME_CANCEL;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
mouseTracking = false;
}
if (browser.get())
browser->SendMouseMoveEvent(0, 0, true);
break;
case WM_MOUSEWHEEL:
if (browser.get()) {
browser->SendMouseWheelEvent(LOWORD(lParam), HIWORD(lParam),
0, GET_WHEEL_DELTA_WPARAM(wParam));
}
break;
case WM_SIZE:
if (browser.get())
browser->WasResized();
break;
case WM_SETFOCUS:
case WM_KILLFOCUS:
if (browser.get())
browser->SendFocusEvent(message == WM_SETFOCUS);
break;
case WM_CAPTURECHANGED:
case WM_CANCELMODE:
if (!mouseRotation) {
if (browser.get())
browser->SendCaptureLostEvent();
}
break;
case WM_SYSCHAR:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
case WM_IME_CHAR: {
CefKeyEvent event;
event.windows_key_code = wParam;
event.native_key_code = lParam;
event.is_system_key = message == WM_SYSCHAR ||
message == WM_SYSKEYDOWN ||
message == WM_SYSKEYUP;
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
event.type = KEYEVENT_RAWKEYDOWN;
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
event.type = KEYEVENT_KEYUP;
else
event.type = KEYEVENT_CHAR;
if (browser.get())
browser->SendKeyEvent(event);
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
RECT rc;
BeginPaint(hWnd, &ps);
rc = ps.rcPaint;
EndPaint(hWnd, &ps);
if (browser.get()) {
browser->Invalidate(CefRect(rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top));
}
return 0;
}
case WM_ERASEBKGND:
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}

View File

@ -0,0 +1,83 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_
#pragma once
#include "include/cef_render_handler.h"
#include "tests/cefclient/osrenderer.h"
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public CefRenderHandler {
public:
// Create a new OSRWindow instance. |browser_provider| must outlive this
// object.
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent);
static CefRefPtr<OSRWindow> From(CefRefPtr<CefRenderHandler> renderHandler);
// Create the underlying window.
bool CreateWidget(HWND hWndParent, const RECT& rect,
HINSTANCE hInst, LPCTSTR className);
// Destroy the underlying window.
void DestroyWidget();
HWND hwnd() const {
return hWnd_;
}
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
private:
OSRWindow(OSRBrowserProvider* browser_provider, bool transparent);
virtual ~OSRWindow();
void EnableGL();
void DisableGL();
void Reset();
static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam);
ClientOSRenderer renderer_;
OSRBrowserProvider* browser_provider_;
HWND hWnd_;
HDC hDC_;
HGLRC hRC_;
IMPLEMENT_REFCOUNTING(OSRWindow);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_WIN_H_

View File

@ -14,6 +14,7 @@
#include "include/cef_frame.h" #include "include/cef_frame.h"
#include "include/cef_runnable.h" #include "include/cef_runnable.h"
#include "cefclient/binding_test.h" #include "cefclient/binding_test.h"
#include "cefclient/cefclient_osr_widget_win.h"
#include "cefclient/client_handler.h" #include "cefclient/client_handler.h"
#include "cefclient/dialog_test.h" #include "cefclient/dialog_test.h"
#include "cefclient/dom_test.h" #include "cefclient/dom_test.h"
@ -31,6 +32,7 @@
HINSTANCE hInst; // current instance HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
TCHAR szOSRWindowClass[MAX_LOADSTRING]; // the OSR window class name
char szWorkingDir[MAX_PATH]; // The current working directory char szWorkingDir[MAX_PATH]; // The current working directory
// Forward declarations of functions included in this code module: // Forward declarations of functions included in this code module:
@ -42,6 +44,15 @@ INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
// The global ClientHandler reference. // The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler; extern CefRefPtr<ClientHandler> g_handler;
class MainBrowserProvider : public OSRBrowserProvider {
virtual CefRefPtr<CefBrowser> GetBrowser() {
if (g_handler.get())
return g_handler->GetBrowser();
return NULL;
}
} g_main_browser_provider;
#if defined(OS_WIN) #if defined(OS_WIN)
// Add Common Controls to the application manifest because it's required to // Add Common Controls to the application manifest because it's required to
// support the default tooltip implementation. // support the default tooltip implementation.
@ -87,6 +98,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
// Initialize global strings // Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CEFCLIENT, szWindowClass, MAX_LOADSTRING); LoadString(hInstance, IDC_CEFCLIENT, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, IDS_OSR_WIDGET_CLASS, szOSRWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); MyRegisterClass(hInstance);
// Perform application initialization // Perform application initialization
@ -298,8 +310,17 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// Populate the settings based on command line arguments. // Populate the settings based on command line arguments.
AppGetBrowserSettings(settings); AppGetBrowserSettings(settings);
// Initialize window info to the defaults for a child window if (AppIsOffScreenRenderingEnabled()) {
info.SetAsChild(hWnd, rect); CefRefPtr<OSRWindow> osr_window =
OSRWindow::Create(&g_main_browser_provider, false);
osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
info.SetAsOffScreen(osr_window->hwnd());
info.SetTransparentPainting(FALSE);
g_handler->SetOSRHandler(osr_window.get());
} else {
// Initialize window info to the defaults for a child window.
info.SetAsChild(hWnd, rect);
}
// Creat the new child browser window // Creat the new child browser window
CefBrowserHost::CreateBrowser(info, g_handler.get(), CefBrowserHost::CreateBrowser(info, g_handler.get(),
@ -525,6 +546,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
case WM_DESTROY: case WM_DESTROY:
// The frame window has exited // The frame window has exited
if (g_handler->GetOSRHandler().get()) {
OSRWindow::From(g_handler->GetOSRHandler())->DestroyWidget();
g_handler->SetOSRHandler(NULL);
}
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
} }

View File

@ -216,7 +216,6 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
const CefKeyEvent& event, const CefKeyEvent& event,
CefEventHandle os_event, CefEventHandle os_event,
bool* is_keyboard_shortcut) { bool* is_keyboard_shortcut) {
ASSERT(m_bFocusOnEditableField == event.focus_on_editable_field);
if (!event.focus_on_editable_field && event.windows_key_code == 0x20) { if (!event.focus_on_editable_field && event.windows_key_code == 0x20) {
// Special handling for the space character when an input element does not // Special handling for the space character when an input element does not
// have focus. Handling the event in OnPreKeyEvent() keeps the event from // have focus. Handling the event in OnPreKeyEvent() keeps the event from
@ -244,6 +243,19 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
} }
} }
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
if (parentBrowser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return true;
}
return false;
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) { bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD(); REQUIRE_UI_THREAD();
@ -414,6 +426,61 @@ void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
allow_os_execution = true; allow_os_execution = true;
} }
bool ClientHandler::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetRootScreenRect(browser, rect);
}
bool ClientHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetViewRect(browser, rect);
}
bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
if (!m_OSRHandler.get())
return false;
return m_OSRHandler->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
}
void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!m_OSRHandler.get())
return;
return m_OSRHandler->OnPopupShow(browser, show);
}
void ClientHandler::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (!m_OSRHandler.get())
return;
return m_OSRHandler->OnPopupSize(browser, rect);
}
void ClientHandler::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) {
if (!m_OSRHandler.get())
return;
m_OSRHandler->OnPaint(browser, type, dirtyRects, buffer, width, height);
}
void ClientHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
if (!m_OSRHandler.get())
return;
m_OSRHandler->OnCursorChange(browser, cursor);
}
void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) { void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
AutoLock lock_scope(this); AutoLock lock_scope(this);
m_MainHwnd = hwnd; m_MainHwnd = hwnd;
@ -617,3 +684,4 @@ bool ClientHandler::ExecuteTestMenu(int command_id) {
// Allow default handling to proceed. // Allow default handling to proceed.
return false; return false;
} }

View File

@ -27,6 +27,7 @@ class ClientHandler : public CefClient,
public CefKeyboardHandler, public CefKeyboardHandler,
public CefLifeSpanHandler, public CefLifeSpanHandler,
public CefLoadHandler, public CefLoadHandler,
public CefRenderHandler,
public CefRequestHandler { public CefRequestHandler {
public: public:
// Interface for process message delegates. Do not perform work in the // Interface for process message delegates. Do not perform work in the
@ -90,6 +91,9 @@ class ClientHandler : public CefClient,
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE { virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
return this; return this;
} }
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
return this; return this;
} }
@ -152,6 +156,13 @@ class ClientHandler : public CefClient,
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE; virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE; virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool OnBeforePopup(
CefRefPtr<CefBrowser> parentBrowser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
// CefLoadHandler methods // CefLoadHandler methods
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser, virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
@ -180,9 +191,35 @@ class ClientHandler : public CefClient,
const CefString& url, const CefString& url,
bool& allow_os_execution) OVERRIDE; bool& allow_os_execution) OVERRIDE;
// CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE;
void SetMainHwnd(CefWindowHandle hwnd); void SetMainHwnd(CefWindowHandle hwnd);
CefWindowHandle GetMainHwnd() { return m_MainHwnd; } CefWindowHandle GetMainHwnd() { return m_MainHwnd; }
void SetEditHwnd(CefWindowHandle hwnd); void SetEditHwnd(CefWindowHandle hwnd);
void SetOSRHandler(CefRefPtr<CefRenderHandler> handler) {
m_OSRHandler = handler;
}
CefRefPtr<CefRenderHandler> GetOSRHandler() { return m_OSRHandler; }
void SetButtonHwnds(CefWindowHandle backHwnd, void SetButtonHwnds(CefWindowHandle backHwnd,
CefWindowHandle forwardHwnd, CefWindowHandle forwardHwnd,
CefWindowHandle reloadHwnd, CefWindowHandle reloadHwnd,
@ -261,6 +298,8 @@ class ClientHandler : public CefClient,
CefWindowHandle m_StopHwnd; CefWindowHandle m_StopHwnd;
CefWindowHandle m_ReloadHwnd; CefWindowHandle m_ReloadHwnd;
CefRefPtr<CefRenderHandler> m_OSRHandler;
// Support for logging. // Support for logging.
std::string m_LogFile; std::string m_LogFile;

View File

@ -57,6 +57,7 @@ const char kAcceleratedVideoDisabled[] = "accelerated-video-disabled";
const char kAcceledated2dCanvasDisabled[] = "accelerated-2d-canvas-disabled"; const char kAcceledated2dCanvasDisabled[] = "accelerated-2d-canvas-disabled";
const char kAcceleratedPluginsDisabled[] = "accelerated-plugins-disabled"; const char kAcceleratedPluginsDisabled[] = "accelerated-plugins-disabled";
const char kDeveloperToolsDisabled[] = "developer-tools-disabled"; const char kDeveloperToolsDisabled[] = "developer-tools-disabled";
const char kOffScreenRenderingEnabled[] = "off-screen-rendering-enabled";
// Other attributes. // Other attributes.
const char kProxyType[] = "proxy-type"; const char kProxyType[] = "proxy-type";

View File

@ -53,6 +53,7 @@ extern const char kAcceleratedVideoDisabled[];
extern const char kAcceledated2dCanvasDisabled[]; extern const char kAcceledated2dCanvasDisabled[];
extern const char kAcceleratedPluginsDisabled[]; extern const char kAcceleratedPluginsDisabled[];
extern const char kDeveloperToolsDisabled[]; extern const char kDeveloperToolsDisabled[];
extern const char kOffScreenRenderingEnabled[];
// Other attributes. // Other attributes.
extern const char kProxyType[]; extern const char kProxyType[];

View File

@ -0,0 +1,249 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
#include "cefclient/osrenderer.h"
#include "cefclient/util.h"
#if defined(OS_WIN)
#include <gl/gl.h>
#include <gl/glu.h>
#elif defined(OS_MACOSX)
#include <OpenGL/gl.h>
#else
#error Platform is not supported.
#endif
#ifndef GL_BGR
#define GL_BGR 0x80E0
#endif
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#endif
ClientOSRenderer::ClientOSRenderer(bool transparent)
: transparent_(transparent),
initialized_(false),
texture_id_(0),
view_width_(0),
view_height_(0),
spin_x_(0),
spin_y_(0) {
}
ClientOSRenderer::~ClientOSRenderer() {
Cleanup();
}
void ClientOSRenderer::Initialize() {
if (initialized_)
return;
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Necessary for non-power-of-2 textures to render correctly.
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Create the texture.
glGenTextures(1, &texture_id_);
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
initialized_ = true;
}
void ClientOSRenderer::Cleanup() {
if (texture_id_ != 0)
glDeleteTextures(1, &texture_id_);
}
void ClientOSRenderer::Render() {
if (view_width_ == 0 || view_height_ == 0)
return;
ASSERT(initialized_);
struct {
float tu, tv;
float x, y, z;
} static vertices[] = {
{0.0f, 1.0f, -1.0f, -1.0f, 0.0f},
{1.0f, 1.0f, 1.0f, -1.0f, 0.0f},
{1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 1.0f, 0.0f}
};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Match GL units to screen coordinates.
glViewport(0, 0, view_width_, view_height_);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 0, view_width_, view_height_, 0.1, 100.0);
// Draw the background gradient.
glPushAttrib(GL_ALL_ATTRIB_BITS);
glBegin(GL_QUADS);
glColor4f(1.0, 0.0, 0.0, 1.0); // red
glVertex2f(-1.0, -1.0);
glVertex2f(1.0, -1.0);
glColor4f(0.0, 0.0, 1.0, 1.0); // blue
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
glPopAttrib();
// Rotate the view based on the mouse spin.
if (spin_x_ != 0)
glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f);
if (spin_y_ != 0)
glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f);
if (transparent_) {
// Alpha blending style. Texture values have premultiplied alpha.
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Enable alpha blending.
glEnable(GL_BLEND);
}
// Enable 2D textures.
glEnable(GL_TEXTURE_2D);
// Draw the facets with the texture.
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
glInterleavedArrays(GL_T2F_V3F, 0, vertices);
glDrawArrays(GL_QUADS, 0, 4);
// Disable 2D textures.
glDisable(GL_TEXTURE_2D);
if (transparent_) {
// Disable alpha blending.
glDisable(GL_BLEND);
}
}
void ClientOSRenderer::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!show) {
// Invalidate the previous popup rectangle so that it will be repainted.
browser->GetHost()->Invalidate(popup_rect_);
// Clear the popup rectangle.
popup_rect_.Set(0, 0, 0, 0);
}
}
void ClientOSRenderer::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
if (rect.width > 0 && rect.height > 0)
popup_rect_ = rect;
}
void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer, int width, int height) {
if (!initialized_)
Initialize();
if (transparent_) {
// Enable alpha blending.
glEnable(GL_BLEND);
}
// Enable 2D textures.
glEnable(GL_TEXTURE_2D);
ASSERT(texture_id_ != 0);
glBindTexture(GL_TEXTURE_2D, texture_id_);
if (type == PET_VIEW) {
int old_width = view_width_;
int old_height = view_height_;
view_width_ = width;
view_height_ = height;
glPixelStorei(GL_UNPACK_ROW_LENGTH, view_width_);
if (old_width != view_width_ || old_height != view_height_) {
// Update/resize the whole texture.
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width_, view_height_, 0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
} else {
// Update just the dirty rectangles.
CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();
for (; i != dirtyRects.end(); ++i) {
const CefRect& rect = *i;
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y);
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,
rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
buffer);
}
}
} else if (type == PET_POPUP && popup_rect_.width > 0 &&
popup_rect_.height > 0) {
int skip_pixels = 0, x = popup_rect_.x;
int skip_rows = 0, y = popup_rect_.y;
int width = popup_rect_.width;
int height = popup_rect_.height;
// Adjust the popup to fit inside the view.
if (x < 0) {
skip_pixels = -x;
x = 0;
}
if (y < 0) {
skip_rows = -y;
y = 0;
}
if (x + width > view_width_)
width -= x + width - view_width_;
if (y + height > view_height_)
height -= y + height - view_height_;
// Update the popup rectangle.
glPixelStorei(GL_UNPACK_ROW_LENGTH, popup_rect_.width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
}
// Disable 2D textures.
glDisable(GL_TEXTURE_2D);
if (transparent_) {
// Disable alpha blending.
glDisable(GL_BLEND);
}
}
void ClientOSRenderer::SetSpin(float spinX, float spinY) {
spin_x_ = spinX;
spin_y_ = spinY;
}
void ClientOSRenderer::IncrementSpin(float spinDX, float spinDY) {
spin_x_ -= spinDX;
spin_y_ -= spinDY;
}

View File

@ -0,0 +1,58 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_OSRENDERER_H_
#define CEF_TESTS_CEFCLIENT_OSRENDERER_H_
#pragma once
#include "include/cef_browser.h"
#include "include/cef_render_handler.h"
class ClientOSRenderer {
public:
// The context must outlive this object.
explicit ClientOSRenderer(bool transparent);
virtual ~ClientOSRenderer();
// Initialize the OpenGL environment.
void Initialize();
// Clean up the OpenGL environment.
void Cleanup();
// Render to the screen.
void Render();
// Forwarded from CefRenderHandler callbacks.
void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show);
void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect);
void OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer, int width, int height);
// Apply spin.
void SetSpin(float spinX, float spinY);
void IncrementSpin(float spinDX, float spinDY);
bool IsTransparent() { return transparent_; }
int GetViewWidth() { return view_width_; }
int GetViewHeight() { return view_height_; }
private:
bool transparent_;
bool initialized_;
unsigned int texture_id_;
int view_width_;
int view_height_;
CefRect popup_rect_;
float spin_x_;
float spin_y_;
};
#endif // CEF_TESTS_CEFCLIENT_OSRENDERER_H_

View File

@ -16,6 +16,7 @@
#define IDI_CEFCLIENT 107 #define IDI_CEFCLIENT 107
#define IDI_SMALL 108 #define IDI_SMALL 108
#define IDC_CEFCLIENT 109 #define IDC_CEFCLIENT 109
#define IDS_OSR_WIDGET_CLASS 110
#define IDR_MAINFRAME 128 #define IDR_MAINFRAME 128
#define IDC_NAV_BACK 200 #define IDC_NAV_BACK 200
#define IDC_NAV_FORWARD 201 #define IDC_NAV_FORWARD 201
@ -68,6 +69,6 @@
#define _APS_NEXT_RESOURCE_VALUE 130 #define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32774 #define _APS_NEXT_COMMAND_VALUE 32774
#define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110 #define _APS_NEXT_SYMED_VALUE 111
#endif #endif
#endif #endif

View File

@ -0,0 +1,530 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/cef_runnable.h"
#include "tests/unittests/test_handler.h"
namespace {
const char kTestUrl[] = "http://tests/OSRTest";
// this html should render on a 600 x 400 window with a little vertical
// offset with scrollbar.
const char kOsrHtml[] =
"<html> "
" <head><title>OSR Test</title></head> "
" <style> "
" .red_hover:hover {color:red;} "
" </style> "
" <script> "
" function getElement(id) { return document.getElementById(id); } "
" function makeH1Red() { getElement('LI00').style.color='red'; } "
" function makeH1Black() { getElement('LI00').style.color='black'; } "
" function navigate() { location.href='?k='+getElement('editbox').value; } "
" </script> "
" <body onfocus='makeH1Red()' onblur='makeH1Black()'> "
" <h1 id='LI00'>OSR Testing h1 - Focus and blur this page and will get this "
" red black</h1> "
" <ol> "
" <li id='LI01'>OnPaint should be called each time a page loads</li> "
" <li id='LI02' style='cursor:pointer;'><span>Move mouse "
" to require an OnCursorChange call</span></li> "
" <li id='LI03' class='red_hover'><span>Hover will color this with "
" red. Will trigger OnPaint once on enter and once on leave</span></li> "
" <li id='LI04'>Right clicking will show contextual menu and will request "
" GetScreenPoint</li> "
" <li id='LI05'>IsWindowRenderingDisabled should be true</li> "
" <li id='LI06'>WasResized should trigger full repaint if size changes. "
" </li> "
" <li id='LI07'>Invalidate should trigger OnPaint once</li> "
" <li id='LI08'>Click and write here with SendKeyEvent to trigger repaints: "
" <input id='editbox' type='text' value=''></li> "
" <li id='LI09'>Click here with SendMouseClickEvent to navigate: "
" <input id='btnnavigate' type='button' onclick='navigate()' "
" value='Click here to navigate' id='editbox' /></li> "
" <li id='LI10' title='EXPECTED_TOOLTIP'>Mouse over this element will "
" trigger show a tooltip</li> "
" </ol> "
" <br /> "
" <br /> "
" <br /> "
" <br /> "
" </body> "
"</html> ";
// #define(DEBUGGER_ATTACHED)
// default osr widget size
const int kOsrWidth = 600;
const int kOsrHeight = 400;
// precomputed bounding client rects for html elements (h1 and li).
const CefRect kExpectedRectLI[] = {
CefRect(8, 8, 567, 74), // LI00
CefRect(27, 103, 548, 20), // LI01
CefRect(27, 123, 548, 20), // LI02
CefRect(27, 143, 548, 20), // LI03
CefRect(27, 163, 548, 20), // LI04
CefRect(27, 183, 548, 20), // LI05
CefRect(27, 203, 548, 20), // LI06
CefRect(27, 223, 548, 20), // LI07
CefRect(27, 243, 548, 26), // LI08
CefRect(27, 269, 548, 26), // LI09
CefRect(27, 295, 548, 20), // LI10
};
// bounding client rects for edit box and navigate button
const CefRect kEditBoxRect(412, 245, 153, 22);
const CefRect kNavigateButtonRect(360, 271, 140, 22);
const int kVerticalScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
const int kHorizontalScrollbarWidth = GetSystemMetrics(SM_CXHSCROLL);
// adjusted expected rect regarding system vertical scrollbar width
CefRect ExpectedRect(int index) {
// this is the scrollbar width for all the kExpectedRectLI
const int kDefaultVerticalScrollbarWidth = 17;
if (kDefaultVerticalScrollbarWidth == kVerticalScrollbarWidth)
return kExpectedRectLI[index];
CefRect adjustedRect(kExpectedRectLI[index]);
adjustedRect.width += kDefaultVerticalScrollbarWidth -
kVerticalScrollbarWidth;
return adjustedRect;
}
// word to be written into edit box
const char kKeyTestWord[] = "done";
// width for the icon that appear on the screen when pressing
// middle mouse button
const int kMiddleButtonIconWidth = 16;
// test type
enum OSRTestType {
// IsWindowRenderingDisabled should be true
OSR_TEST_IS_WINDOWLESS,
// focusing webview, LI00 will get red & repainted
OSR_TEST_FOCUS,
// loading webview should trigger a full paint (L01)
OSR_TEST_PAINT,
// moving mouse over L02, OnCursorChange will be called
OSR_TEST_CURSOR,
// moving mouse on L03, OnPaint will be called for its bounding rectangle
OSR_TEST_MOUSE_MOVE,
// right clicking an element (L04), OnBeforeContextMenu should be called
OSR_TEST_CLICK_RIGHT,
// right clicking an element (L04), context menu will query screen point
OSR_TEST_SCREEN_POINT,
// left click in text box should query repainting edit box area
OSR_TEST_CLICK_LEFT,
// clicking middle mouse button, will draw the scroll icon
OSR_TEST_CLICK_MIDDLE,
// Resize should trigger a full repaint with the new given size
OSR_TEST_RESIZE,
// Invalidate should trigger repaint synchronously
OSR_TEST_INVALIDATE,
// write into editbox LI08, click to navigate on LI09
OSR_TEST_KEY_EVENTS,
// mouse over LI10 will show a tooltip
OSR_TEST_TOOLTIP,
// mouse wheel will trigger a scroll event
OSR_TEST_SCROLLING,
};
// Used in the browser process.
class OSRTestHandler : public TestHandler,
public CefRenderHandler,
public CefContextMenuHandler {
public:
explicit OSRTestHandler(OSRTestType test)
: test_type_(test),
started_(false),
succeeded_(false) {
}
virtual ~OSRTestHandler() {}
// TestHandler methods
virtual void RunTest() OVERRIDE {
AddResource(kTestUrl, kOsrHtml, "text/html");
CreateOSRBrowser(kTestUrl);
#if !defined(DEBUGGER_ATTACHED)
// Each test has a 5 second timeout. After this timeout it will be destroyed
// and the test will fail. DestroyTest will be called at the timeout even
// if the test is already destroyed and this is fine.
CefPostDelayedTask(TID_UI, NewCefRunnableMethod(this,
&OSRTestHandler::DestroyTest), 5000);
#endif // DEBUGGER_ATTACHED
}
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE {
if (test_type_ == OSR_TEST_IS_WINDOWLESS) {
EXPECT_TRUE(browser->GetHost()->IsWindowRenderingDisabled());
DestroySucceededTestSoon();
}
TestHandler::OnAfterCreated(browser);
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
if (test_type_ == OSR_TEST_KEY_EVENTS && started()) {
std::string expectedUrl = std::string(kTestUrl) + "?k=" + kKeyTestWord;
EXPECT_EQ(frame->GetURL(), expectedUrl);
DestroySucceededTestSoon();
}
}
// CefClient methods, providing handlers
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE {
return this;
}
// CefRenderHandler methods
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE {
if (test_type_ == OSR_TEST_RESIZE && started()) {
rect = CefRect(0, 0, kOsrWidth * 2, kOsrHeight * 2);
return true;
}
rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
return true;
}
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE {
if (test_type_ == OSR_TEST_SCREEN_POINT && started()) {
EXPECT_EQ(viewX, MiddleX(ExpectedRect(4)));
EXPECT_EQ(viewY, MiddleY(ExpectedRect(4)));
DestroySucceededTestSoon();
}
// we don't want to see a contextual menu. stop here.
return false;
}
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE {
// popup widgets are not yet supported
EXPECT_FALSE("OnPopupShow should not be reached");
}
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE {
// popup widgets are not yet supported
EXPECT_FALSE("OnPopupSize should not be reached");
}
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) OVERRIDE {
// bitmap must as big as GetViewRect said
if (test_type_ != OSR_TEST_RESIZE || !started()) {
EXPECT_EQ(kOsrWidth, width);
EXPECT_EQ(kOsrHeight, height);
}
EXPECT_TRUE(browser->GetHost()->IsWindowRenderingDisabled());
// We don't support popup widgets yet
EXPECT_EQ(type, PET_VIEW);
// start test only when painting something else then background
if (IsBackgroundInBuffer(reinterpret_cast<const uint32*>(buffer),
width * height, RGB(255, 255, 255))) {
return;
}
// Send events after the first full repaint
switch (test_type_) {
case OSR_TEST_PAINT:
// test that we have a full repaint
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_TRUE(IsFullRepaint(dirtyRects[0]));
DestroySucceededTestSoon();
break;
case OSR_TEST_FOCUS:
if (StartTest()) {
// body.onfocus will make LI00 red
browser->GetHost()->SendFocusEvent(true);
} else {
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_EQ(dirtyRects[0], ExpectedRect(0));
DestroySucceededTestSoon();
}
break;
case OSR_TEST_CURSOR:
if (StartTest()) {
// make mouse leave first
browser->GetHost()->SendMouseMoveEvent(0, 0, true);
// enter mouse in the LI2 element having hand cursor
browser->GetHost()->SendMouseMoveEvent(MiddleX(ExpectedRect(2)),
MiddleY(ExpectedRect(2)), false);
}
break;
case OSR_TEST_MOUSE_MOVE:
if (StartTest()) {
browser->GetHost()->SendMouseMoveEvent(MiddleX(ExpectedRect(3)),
MiddleY(ExpectedRect(3)), false);
} else {
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_EQ(dirtyRects[0], ExpectedRect(3));
DestroySucceededTestSoon();
}
break;
case OSR_TEST_CLICK_RIGHT:
case OSR_TEST_SCREEN_POINT:
if (StartTest()) {
browser->GetHost()->SendMouseClickEvent(MiddleX(ExpectedRect(4)),
MiddleY(ExpectedRect(4)), MBT_RIGHT, false, 1);
browser->GetHost()->SendMouseClickEvent(MiddleX(ExpectedRect(4)),
MiddleY(ExpectedRect(4)), MBT_RIGHT, true, 1);
}
break;
case OSR_TEST_CLICK_LEFT:
if (StartTest()) {
browser->GetHost()->SendMouseClickEvent(MiddleX(kEditBoxRect),
MiddleY(kEditBoxRect), MBT_LEFT, false, 1);
browser->GetHost()->SendMouseClickEvent(MiddleX(kEditBoxRect),
MiddleY(kEditBoxRect), MBT_LEFT, true, 1);
} else {
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_EQ(dirtyRects[0], kEditBoxRect);
DestroySucceededTestSoon();
}
break;
case OSR_TEST_CLICK_MIDDLE:
if (StartTest()) {
browser->GetHost()->SendMouseClickEvent(MiddleX(ExpectedRect(0)),
MiddleY(ExpectedRect(0)), MBT_MIDDLE, false, 1);
browser->GetHost()->SendMouseClickEvent(MiddleX(ExpectedRect(0)),
MiddleY(ExpectedRect(0)), MBT_MIDDLE, true, 1);
} else {
EXPECT_EQ(dirtyRects.size(), 1);
CefRect expectedRect(
MiddleX(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
MiddleY(ExpectedRect(0)) - kMiddleButtonIconWidth / 2,
kMiddleButtonIconWidth, kMiddleButtonIconWidth);
EXPECT_EQ(dirtyRects[0], expectedRect);
DestroySucceededTestSoon();
}
break;
case OSR_TEST_RESIZE:
if (StartTest()) {
browser->GetHost()->WasResized();
} else {
EXPECT_EQ(kOsrWidth * 2, width);
EXPECT_EQ(kOsrHeight * 2, height);
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_TRUE(IsFullRepaint(dirtyRects[0], width, height));
DestroySucceededTestSoon();
}
break;
case OSR_TEST_INVALIDATE: {
static bool invalidating = false;
static const CefRect invalidate_rect(0, 0, 1, 1);
if (StartTest()) {
invalidating = true;
browser->GetHost()->Invalidate(invalidate_rect);
invalidating = false;
} else {
EXPECT_TRUE(invalidating);
EXPECT_EQ(dirtyRects.size(), 1);
EXPECT_EQ(dirtyRects[0], invalidate_rect);
DestroySucceededTestSoon();
}
break;
}
case OSR_TEST_KEY_EVENTS:
if (StartTest()) {
// click inside edit box
browser->GetHost()->SendMouseClickEvent(MiddleX(kEditBoxRect),
MiddleY(kEditBoxRect), MBT_LEFT, false, 1);
browser->GetHost()->SendMouseClickEvent(MiddleX(kEditBoxRect),
MiddleY(kEditBoxRect), MBT_LEFT, true, 1);
// write "done" word
CefKeyEvent event;
event.is_system_key = false;
size_t word_lenght = strlen(kKeyTestWord);
for (size_t i = 0; i < word_lenght; ++i) {
BYTE VkCode = LOBYTE(VkKeyScanA(kKeyTestWord[i]));
UINT scanCode = MapVirtualKey(VkCode, MAPVK_VK_TO_VSC);
event.native_key_code = (scanCode << 16) | // key scan code
1; // key repeat count
event.windows_key_code = VkCode;
event.type = KEYEVENT_RAWKEYDOWN;
browser->GetHost()->SendKeyEvent(event);
event.windows_key_code = kKeyTestWord[i];
event.type = KEYEVENT_CHAR;
browser->GetHost()->SendKeyEvent(event);
event.windows_key_code = VkCode;
// bits 30 and 31 should be always 1 for WM_KEYUP
event.native_key_code |= 0xC0000000;
event.type = KEYEVENT_KEYUP;
browser->GetHost()->SendKeyEvent(event);
}
// click button to navigate
browser->GetHost()->SendMouseClickEvent(MiddleX(kNavigateButtonRect),
MiddleY(kNavigateButtonRect), MBT_LEFT, false, 1);
browser->GetHost()->SendMouseClickEvent(MiddleX(kNavigateButtonRect),
MiddleY(kNavigateButtonRect), MBT_LEFT, true, 1);
}
break;
case OSR_TEST_TOOLTIP:
if (StartTest()) {
browser->GetHost()->SendMouseMoveEvent(MiddleX(ExpectedRect(10)),
MiddleY(ExpectedRect(10)), false);
}
break;
case OSR_TEST_SCROLLING: {
static const int deltaY = 10;
if (StartTest()) {
// scroll down once
browser->GetHost()->SendMouseWheelEvent(MiddleX(ExpectedRect(0)),
MiddleY(ExpectedRect(0)), 0, - deltaY);
} else {
// there should be 3 update areas:
// 1) vertical scrollbar
// 2) discovered new area (bottom side)
// 3) the whole visible rect.
EXPECT_EQ(dirtyRects.size(), 3);
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
kOsrWidth - kVerticalScrollbarWidth, kHorizontalScrollbarWidth));
EXPECT_EQ(dirtyRects[1], CefRect(0, kHorizontalScrollbarWidth,
kOsrWidth, kOsrHeight - 2 * kHorizontalScrollbarWidth));
EXPECT_EQ(dirtyRects[2],
CefRect(0, kOsrHeight - kHorizontalScrollbarWidth,
kOsrWidth - kVerticalScrollbarWidth,
kHorizontalScrollbarWidth));
DestroySucceededTestSoon();
}
break;
}
}
}
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) OVERRIDE {
if (test_type_ == OSR_TEST_CURSOR && started()) {
DestroySucceededTestSoon();
}
}
virtual bool OnTooltip(CefRefPtr<CefBrowser> browser,
CefString& text) OVERRIDE {
if (test_type_ == OSR_TEST_TOOLTIP && started()) {
EXPECT_EQ(text, "EXPECTED_TOOLTIP");
DestroySucceededTestSoon();
}
return false;
}
virtual void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model) OVERRIDE {
if (test_type_ == OSR_TEST_CLICK_RIGHT && started()) {
EXPECT_EQ(params->GetXCoord(), MiddleX(ExpectedRect(4)));
EXPECT_EQ(params->GetYCoord(), MiddleY(ExpectedRect(4)));
DestroySucceededTestSoon();
}
}
// OSRTestHandler functions
void CreateOSRBrowser(const CefString& url) {
CefWindowInfo windowInfo;
CefBrowserSettings settings;
windowInfo.SetAsOffScreen(GetDesktopWindow());
CefBrowserHost::CreateBrowser(windowInfo, this, url, settings);
}
bool IsFullRepaint(const CefRect& rc, int width = kOsrWidth,
int height = kOsrHeight) {
return rc.width == width && rc.height == height;
}
static
bool IsBackgroundInBuffer(const uint32* buffer, size_t size, uint32 rgba) {
for (size_t i = 0; i < size; i++) {
if (buffer[i] != rgba) {
return false;
}
}
return true;
}
static inline int MiddleX(const CefRect& rect) {
return rect.x + rect.width / 2;
}
static inline int MiddleY(const CefRect& rect) {
return rect.y + rect.height / 2;
}
void DestroySucceededTestSoon() {
succeeded_ = true;
CefPostTask(TID_IO, NewCefRunnableMethod(this,
&OSRTestHandler::DestroyTest));
}
// true if the events for this test are already sent
bool started() { return started_; }
// true if the exit point was reached, even the result is not
// the expected one
bool succeeded() { return succeeded_; }
// will mark test as started and will return true only the first time
// it is called
bool StartTest() {
if (started_)
return false;
started_ = true;
return true;
}
private:
OSRTestType test_type_;
bool started_;
bool succeeded_;
IMPLEMENT_REFCOUNTING(OSRTestHandler);
};
} // namespace
// generic test
#define OSR_TEST(name, test_mode)\
TEST(OSRTest, name) {\
CefRefPtr<OSRTestHandler> handler = \
new OSRTestHandler(test_mode);\
handler->ExecuteTest();\
EXPECT_TRUE(handler->succeeded());\
}
// tests
OSR_TEST(Windowless, OSR_TEST_IS_WINDOWLESS);
OSR_TEST(Focus, OSR_TEST_FOCUS);
OSR_TEST(Paint, OSR_TEST_PAINT);
OSR_TEST(Cursor, OSR_TEST_CURSOR);
OSR_TEST(MouseMove, OSR_TEST_MOUSE_MOVE);
OSR_TEST(MouseRightClick, OSR_TEST_CLICK_RIGHT);
OSR_TEST(MouseLeftClick, OSR_TEST_CLICK_LEFT);
OSR_TEST(MouseMiddleClick, OSR_TEST_CLICK_MIDDLE);
OSR_TEST(ScreenPoint, OSR_TEST_SCREEN_POINT);
OSR_TEST(Resize, OSR_TEST_RESIZE);
OSR_TEST(Invalidate, OSR_TEST_INVALIDATE);
OSR_TEST(KeyEvents, OSR_TEST_KEY_EVENTS);
OSR_TEST(Tooltip, OSR_TEST_TOOLTIP);
OSR_TEST(Scrolling, OSR_TEST_SCROLLING);