Merge revision 1294 changes:

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

git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/1453@1295 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-06-27 17:43:48 +00:00
parent b1f8bd9ba0
commit d4a37330b8
18 changed files with 976 additions and 119 deletions

View File

@ -209,7 +209,7 @@
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'<(DEPTH)/build/linux/system.gyp:gtk',
'gtk',
],
'sources': [
'<@(includes_linux)',
@ -248,6 +248,7 @@
'tests/cefclient/client_app.h',
'tests/cefclient/client_switches.cpp',
'tests/cefclient/client_switches.h',
'tests/cefclient/res/osr_test.html',
'tests/unittests/command_line_unittest.cc',
'tests/unittests/cookie_unittest.cc',
'tests/unittests/dialog_unittest.cc',
@ -258,6 +259,7 @@
'tests/unittests/jsdialog_unittest.cc',
'tests/unittests/life_span_unittest.cc',
'tests/unittests/navigation_unittest.cc',
'tests/unittests/os_rendering_unittest.cc',
'tests/unittests/process_message_unittest.cc',
'tests/unittests/request_unittest.cc',
'tests/cefclient/resource_util.h',
@ -311,9 +313,7 @@
[ 'OS=="win"', {
'sources': [
'tests/cefclient/cefclient.rc',
'tests/cefclient/res/osr_test.html',
'tests/cefclient/resource_util_win.cpp',
'tests/unittests/os_rendering_unittest.cc',
],
}],
[ 'OS=="mac"', {
@ -422,7 +422,6 @@
'sources': [
'tests/cefclient/resource_util_mac.mm',
'tests/cefclient/resource_util_posix.cpp',
'tests/unittests/os_rendering_unittest.cc',
'tests/unittests/os_rendering_unittest_mac.h',
'tests/unittests/os_rendering_unittest_mac.mm',
'tests/unittests/run_all_unittests_mac.mm',
@ -432,6 +431,18 @@
'dependencies': [
'<(DEPTH)/build/linux/system.gyp:gtk',
],
'sources': [
'tests/cefclient/resource_util_linux.cpp',
'tests/cefclient/resource_util_posix.cpp',
],
'copies': [
{
'destination': '<(PRODUCT_DIR)/files',
'files': [
'tests/cefclient/res/osr_test.html',
],
},
],
}],
],
},
@ -821,6 +832,8 @@
],
'sources': [
'<@(includes_common)',
'libcef/browser/backing_store_osr.cc',
'libcef/browser/backing_store_osr.h',
'libcef/browser/browser_context.cc',
'libcef/browser/browser_context.h',
'libcef/browser/browser_host_impl.cc',
@ -878,6 +891,8 @@
'libcef/browser/path_util_impl.cc',
'libcef/browser/process_util_impl.cc',
'libcef/browser/proxy_stubs.cc',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/resource_dispatcher_host_delegate.cc',
'libcef/browser/resource_dispatcher_host_delegate.h',
'libcef/browser/resource_request_job.cc',
@ -904,6 +919,8 @@
'libcef/browser/url_request_context_proxy.h',
'libcef/browser/url_request_interceptor.cc',
'libcef/browser/url_request_interceptor.h',
'libcef/browser/web_contents_view_osr.cc',
'libcef/browser/web_contents_view_osr.h',
'libcef/browser/web_plugin_impl.cc',
'libcef/browser/web_plugin_impl.h',
'libcef/browser/xml_reader_impl.cc',
@ -1011,17 +1028,11 @@
['OS=="win"', {
'sources': [
'<@(includes_win)',
'libcef/browser/backing_store_osr.cc',
'libcef/browser/backing_store_osr.h',
'libcef/browser/browser_host_impl_win.cc',
'libcef/browser/browser_main_win.cc',
'libcef/browser/javascript_dialog_win.cc',
'libcef/browser/menu_creator_runner_win.cc',
'libcef/browser/menu_creator_runner_win.h',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/web_contents_view_osr.cc',
'libcef/browser/web_contents_view_osr.h',
# Include sources for context menu implementation.
'<(DEPTH)/ui/views/controls/menu/menu_2.cc',
'<(DEPTH)/ui/views/controls/menu/menu_2.h',
@ -1039,20 +1050,14 @@
'<@(includes_mac)',
'libcef/browser/application_mac.h',
'libcef/browser/application_mac.mm',
'libcef/browser/backing_store_osr.cc',
'libcef/browser/backing_store_osr.h',
'libcef/browser/browser_host_impl_mac.mm',
'libcef/browser/browser_main_mac.mm',
'libcef/browser/javascript_dialog_mac.mm',
'libcef/browser/menu_creator_runner_mac.h',
'libcef/browser/menu_creator_runner_mac.mm',
'libcef/browser/render_widget_host_view_osr_mac.mm',
'libcef/browser/render_widget_host_view_osr.cc',
'libcef/browser/render_widget_host_view_osr.h',
'libcef/browser/text_input_client_osr_mac.mm',
'libcef/browser/text_input_client_osr_mac.h',
'libcef/browser/web_contents_view_osr.cc',
'libcef/browser/web_contents_view_osr.h',
# Include sources for context menu implementation.
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.mm',
'<(DEPTH)/chrome/browser/ui/cocoa/event_utils.h',
@ -1337,5 +1342,32 @@
}, # target cef_unittests_helper_app
],
}], # OS=="mac"
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'targets': [
{
'target_name': 'gtk',
'type': 'none',
'variables': {
# gtk requires gmodule, but it does not list it as a dependency
# in some misconfigured systems.
# gtkglext is required by the cefclient OSR example.
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0',
},
'direct_dependent_settings': {
'cflags': [
'<!@(pkg-config --cflags <(gtk_packages))',
],
},
'link_settings': {
'ldflags': [
'<!@(pkg-config --libs-only-L --libs-only-other <(gtk_packages))',
],
'libraries': [
'<!@(pkg-config --libs-only-l <(gtk_packages))',
],
},
},
],
}], # OS=="linux" or OS=="freebsd" or OS=="openbsd"
],
}

View File

@ -86,6 +86,7 @@
'tests/cefclient/res/domaccess.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/osr_test.html',
'tests/cefclient/res/other_tests.html',
'tests/cefclient/res/performance.html',
'tests/cefclient/res/transparency.html',
@ -110,6 +111,8 @@
'tests/cefclient/dialog_test.h',
'tests/cefclient/dom_test.cpp',
'tests/cefclient/dom_test.h',
'tests/cefclient/osrenderer.h',
'tests/cefclient/osrenderer.cpp',
'tests/cefclient/performance_test.cpp',
'tests/cefclient/performance_test.h',
'tests/cefclient/performance_test_setup.h',
@ -130,11 +133,8 @@
'tests/cefclient/cefclient_osr_widget_win.cpp',
'tests/cefclient/cefclient_win.cpp',
'tests/cefclient/client_handler_win.cpp',
'tests/cefclient/osrenderer.h',
'tests/cefclient/osrenderer.cpp',
'tests/cefclient/resource.h',
'tests/cefclient/res/cefclient.ico',
'tests/cefclient/res/osr_test.html',
'tests/cefclient/res/small.ico',
'tests/cefclient/resource_util_win.cpp',
'tests/cefclient/window_test_win.cpp',
@ -144,8 +144,6 @@
'tests/cefclient/cefclient_osr_widget_mac.h',
'tests/cefclient/cefclient_osr_widget_mac.mm',
'tests/cefclient/client_handler_mac.mm',
'tests/cefclient/osrenderer.h',
'tests/cefclient/osrenderer.cpp',
'tests/cefclient/resource_util_mac.mm',
'tests/cefclient/resource_util_posix.cpp',
'tests/cefclient/window_test_mac.mm',
@ -189,11 +187,12 @@
'tests/cefclient/mac/English.lproj/InfoPlist.strings',
'tests/cefclient/mac/English.lproj/MainMenu.xib',
'tests/cefclient/mac/Info.plist',
'tests/cefclient/res/osr_test.html',
'<@(cefclient_bundle_resources_common)',
],
'cefclient_sources_linux': [
'tests/cefclient/cefclient_gtk.cpp',
'tests/cefclient/cefclient_osr_widget_gtk.h',
'tests/cefclient/cefclient_osr_widget_gtk.cpp',
'tests/cefclient/client_handler_gtk.cpp',
'tests/cefclient/resource_util_linux.cpp',
'tests/cefclient/resource_util_posix.cpp',

View File

@ -109,8 +109,10 @@ struct CefWindowInfoTraits {
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
target->widget = src->widget;
target->parent_widget = src->parent_widget;
target->window_rendering_disabled = src->window_rendering_disabled;
target->transparent_painting = src->transparent_painting;
target->widget = src->widget;
}
};
@ -126,6 +128,15 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
void SetAsChild(CefWindowHandle ParentWidget) {
parent_widget = ParentWidget;
}
void SetTransparentPainting(bool transparentPainting) {
transparent_painting = transparentPainting;
}
void SetAsOffScreen(CefWindowHandle ParentWidget) {
window_rendering_disabled = true;
parent_widget = ParentWidget;
}
};
#endif // OS_LINUX

View File

@ -43,7 +43,7 @@ extern "C" {
#endif
// Handle types.
#define cef_cursor_handle_t void*
#define cef_cursor_handle_t GdkCursor*
#define cef_event_handle_t GdkEvent*
#define cef_window_handle_t GtkWidget*
#define cef_text_input_context_t void*
@ -63,6 +63,14 @@ typedef struct _cef_window_info_t {
// Pointer for the parent GtkBox widget.
cef_window_handle_t parent_widget;
// If window rendering is disabled no browser window will be created. Set
// |parent_widget| to the window that will act as the parent for popup menus,
// dialog boxes, etc.
bool window_rendering_disabled;
// Set to true to enable transparent painting.
bool transparent_painting;
// Pointer for the new browser widget.
cef_window_handle_t widget;
} cef_window_info_t;

View File

@ -17,10 +17,12 @@
#include "libcef/browser/devtools_delegate.h"
#include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/navigate_params.h"
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/scheme_registration.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/url_request_context_getter.h"
#include "libcef/browser/url_request_context_getter_proxy.h"
#include "libcef/browser/web_contents_view_osr.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/drag_data_impl.h"
@ -48,11 +50,6 @@
#include "content/public/common/file_chooser_params.h"
#include "ui/shell_dialogs/selected_file_info.h"
#if defined(OS_WIN) || defined(OS_MACOSX)
#include "libcef/browser/render_widget_host_view_osr.h"
#include "libcef/browser/web_contents_view_osr.h"
#endif
namespace {
class CreateBrowserHelper {
@ -348,9 +345,6 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
return NULL;
}
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
#if defined(OS_WIN) || defined(OS_MACOSX)
if (browser->IsWindowRenderingDisabled()) {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
@ -358,7 +352,6 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
if (view)
view->set_browser_impl(browser);
}
#endif // defined(OS_WIN) || defined(OS_MACOSX)
if (client.get()) {
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
@ -691,16 +684,10 @@ void CefBrowserHostImpl::NotifyScreenInfoChanged() {
if (!view)
return;
#if defined(OS_WIN) || defined(OS_MACOSX)
CefRenderWidgetHostViewOSR* orview =
static_cast<CefRenderWidgetHostViewOSR*>(view);
orview->OnScreenInfoChanged();
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
@ -719,7 +706,6 @@ void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
if (!web_contents())
return;
#if defined(OS_WIN) || defined(OS_MACOSX)
content::RenderWidgetHostView* view =
web_contents()->GetRenderViewHost()->GetView();
CefRenderWidgetHostViewOSR* orview =
@ -730,11 +716,6 @@ void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
dirtyRect.width, dirtyRect.height);
orview->Invalidate(rect, type);
}
#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) {
@ -752,7 +733,6 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
if (widget)
widget->ForwardKeyboardEvent(web_event);
} else {
#if defined(OS_WIN) || defined(OS_MACOSX)
if (!web_contents())
return;
content::RenderWidgetHostView* view =
@ -761,11 +741,6 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
static_cast<CefRenderWidgetHostViewOSR*>(view);
if (orview)
orview->SendKeyEvent(web_event);
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
}
@ -816,7 +791,6 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
if (widget)
widget->ForwardWheelEvent(web_event);
} else {
#if defined(OS_WIN) || defined(OS_MACOSX)
if (!web_contents())
return;
content::RenderWidgetHostView* view =
@ -826,11 +800,6 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
if (orview)
orview->SendMouseWheelEvent(web_event);
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
}
@ -870,7 +839,6 @@ void CefBrowserHostImpl::SendMouseEvent(const WebKit::WebMouseEvent& event) {
if (widget)
widget->ForwardMouseEvent(event);
} else {
#if defined(OS_WIN) || defined(OS_MACOSX)
if (!web_contents())
return;
content::RenderWidgetHostView* view =
@ -880,11 +848,6 @@ void CefBrowserHostImpl::SendMouseEvent(const WebKit::WebMouseEvent& event) {
if (orview)
orview->SendMouseEvent(event);
#else
// TODO(port): Implement this method to work on other platforms as part of
// off-screen rendering support.
NOTREACHED();
#endif
}
}

View File

@ -6,17 +6,21 @@
#include "libcef/browser/browser_host_impl.h"
#include <gtk/gtk.h>
#include <sys/sysinfo.h>
#include "libcef/browser/thread_util.h"
#include "base/bind.h"
#include "base/utf_string_conversions.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/renderer_preferences.h"
#include "grit/cef_strings.h"
#include "grit/ui_strings.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/gtk/WebInputEventFactory.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
@ -231,6 +235,14 @@ bool RunFileDialog(const content::FileChooserParams& params,
return success;
}
// Returns the number of seconds since system boot.
long GetSystemUptime() {
struct sysinfo info;
if (sysinfo(&info) == 0)
return info.uptime;
return 0;
}
} // namespace
bool CefBrowserHostImpl::PlatformCreateWindow() {
@ -308,7 +320,9 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.widget;
return IsWindowRenderingDisabled() ?
window_info_.parent_widget :
window_info_.widget;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
@ -371,49 +385,190 @@ 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;
return info.window_rendering_disabled ? true : false;
}
bool CefBrowserHostImpl::IsTransparent() {
return false;
return window_info_.transparent_painting != 0;
}
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
content::NativeWebKeyboardEvent& native_event,
const CefKeyEvent& event) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) {
// Use a synthetic GdkEventKey in order to obtain the windowsKeyCode member
// from the NativeWebKeyboardEvent constructor. This is the only member
// which cannot be easily translated (without hardcoding keyCodes).
guint state = 0;
if (key_event.modifiers & EVENTFLAG_SHIFT_DOWN)
state |= GDK_SHIFT_MASK;
if (key_event.modifiers & EVENTFLAG_CAPS_LOCK_ON)
state |= GDK_LOCK_MASK;
if (key_event.modifiers & EVENTFLAG_CONTROL_DOWN)
state |= GDK_CONTROL_MASK;
if (key_event.modifiers & EVENTFLAG_ALT_DOWN)
state |= GDK_MOD1_MASK;
if (key_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
state |= GDK_BUTTON1_MASK;
if (key_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
state |= GDK_BUTTON2_MASK;
if (key_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
state |= GDK_BUTTON3_MASK;
GdkKeymap* keymap = gdk_keymap_get_for_display(gdk_display_get_default());
GdkKeymapKey *keys = NULL;
gint n_keys = 0;
if (gdk_keymap_get_entries_for_keyval(keymap, key_event.native_key_code,
&keys, &n_keys)) {
GdkEventKey event;
event.type = GDK_KEY_PRESS;
event.window = NULL;
event.send_event = 0;
event.time = 0;
event.state = state;
event.keyval = key_event.native_key_code;
event.length = 0;
event.string = NULL;
event.hardware_keycode = keys[0].keycode;
event.group = keys[0].group;
event.is_modifier = 0;
g_free(keys);
result = content::NativeWebKeyboardEvent(
reinterpret_cast<GdkEvent*>(&event));
}
result.timeStampSeconds = GetSystemUptime();
switch (key_event.type) {
case KEYEVENT_RAWKEYDOWN:
case KEYEVENT_KEYDOWN:
result.type = WebKit::WebInputEvent::RawKeyDown;
break;
case KEYEVENT_KEYUP:
result.type = WebKit::WebInputEvent::KeyUp;
break;
case KEYEVENT_CHAR:
result.type = WebKit::WebInputEvent::Char;
break;
default:
NOTREACHED();
}
}
void CefBrowserHostImpl::PlatformTranslateClickEvent(
WebKit::WebMouseEvent& ev,
WebKit::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
MouseButtonType type,
bool mouseUp, int clickCount) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
PlatformTranslateMouseEvent(result, mouse_event);
switch (type) {
case MBT_LEFT:
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
WebKit::WebInputEvent::MouseDown;
result.button = WebKit::WebMouseEvent::ButtonLeft;
break;
case MBT_MIDDLE:
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
WebKit::WebInputEvent::MouseDown;
result.button = WebKit::WebMouseEvent::ButtonMiddle;
break;
case MBT_RIGHT:
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
WebKit::WebInputEvent::MouseDown;
result.button = WebKit::WebMouseEvent::ButtonRight;
break;
default:
NOTREACHED();
}
result.clickCount = clickCount;
}
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
WebKit::WebMouseEvent& ev,
WebKit::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
bool mouseLeave) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
PlatformTranslateMouseEvent(result, mouse_event);
if (!mouseLeave) {
result.type = WebKit::WebInputEvent::MouseMove;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonRight;
else
result.button = WebKit::WebMouseEvent::ButtonNone;
} else {
result.type = WebKit::WebInputEvent::MouseLeave;
result.button = WebKit::WebMouseEvent::ButtonNone;
}
result.clickCount = 0;
}
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
WebKit::WebMouseWheelEvent& ev,
WebKit::WebMouseWheelEvent& result,
const CefMouseEvent& mouse_event,
int deltaX, int deltaY) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
result = WebKit::WebMouseWheelEvent();
PlatformTranslateMouseEvent(result, mouse_event);
result.type = WebKit::WebInputEvent::MouseWheel;
static const double scrollbarPixelsPerGtkTick = 40.0;
result.deltaX = deltaX;
result.deltaY = deltaY;
result.wheelTicksX = result.deltaX / scrollbarPixelsPerGtkTick;
result.wheelTicksY = result.deltaY / scrollbarPixelsPerGtkTick;
result.hasPreciseScrollingDeltas = true;
// Unless the phase and momentumPhase are passed in as parameters to this
// function, there is no way to know them
result.phase = WebKit::WebMouseWheelEvent::PhaseNone;
result.momentumPhase = WebKit::WebMouseWheelEvent::PhaseNone;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = WebKit::WebMouseEvent::ButtonRight;
else
result.button = WebKit::WebMouseEvent::ButtonNone;
}
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
WebKit::WebMouseEvent& ev,
WebKit::WebMouseEvent& result,
const CefMouseEvent& mouse_event) {
// TODO(port): Implement this method as part of off-screen rendering support.
NOTIMPLEMENTED();
// position
result.x = mouse_event.x;
result.y = mouse_event.y;
result.windowX = result.x;
result.windowY = result.y;
result.globalX = result.x;
result.globalY = result.y;
// global position
if (IsWindowRenderingDisabled()) {
GetClient()->GetRenderHandler()->GetScreenPoint(GetBrowser(),
result.x, result.y,
result.globalX, result.globalY);
} else {
GtkWidget* window = gtk_widget_get_toplevel(GetWindowHandle());
GdkWindow* gdk_window = gtk_widget_get_window(window);
gint xorigin, yorigin;
gdk_window_get_root_origin(gdk_window, &xorigin, &yorigin);
result.globalX = xorigin + result.x;
result.globalY = yorigin + result.y;
}
// modifiers
result.modifiers |= TranslateModifiers(mouse_event.modifiers);
// timestamp
result.timeStampSeconds = GetSystemUptime();
}

View File

@ -18,6 +18,7 @@
#include "libcef/browser/resource_dispatcher_host_delegate.h"
#include "libcef/browser/speech_recognition_manager_delegate.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/web_contents_view_osr.h"
#include "libcef/browser/web_plugin_impl.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/command_line_impl.h"
@ -37,10 +38,6 @@
#include "googleurl/src/gurl.h"
#include "ui/base/ui_base_switches.h"
#if defined(OS_WIN) || defined(OS_MACOSX)
#include "libcef/browser/web_contents_view_osr.h"
#endif
namespace {
// In-memory store for access tokens used by geolocation.
@ -373,9 +370,7 @@ CefContentBrowserClient::OverrideCreateWebContentsView(
content::RenderViewHostDelegateView** render_view_host_delegate_view) {
content::WebContentsViewPort* 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) || defined(OS_MACOSX)
CefBrowserContext* browserContext =
static_cast<CefBrowserContext*>(web_contents->GetBrowserContext());
@ -385,7 +380,6 @@ CefContentBrowserClient::OverrideCreateWebContentsView(
*render_view_host_delegate_view = view_or;
view = view_or;
}
#endif // defined(OS_WIN) || defined(OS_MACOSX)
return view;
}

View File

@ -22,25 +22,53 @@ class CefMenuDelegate : public MenuGtk::Delegate {
CefMenuCreatorRunnerGtk::CefMenuCreatorRunnerGtk() {
}
CefMenuCreatorRunnerGtk::~CefMenuCreatorRunnerGtk() {
if (menu_.get())
menu_->Cancel();
}
bool CefMenuCreatorRunnerGtk::RunContextMenu(CefMenuCreator* manager) {
gfx::Point screen_point;
GdkEventButton* event = NULL;
if (manager->browser()->IsWindowRenderingDisabled()) {
CefRefPtr<CefClient> client = manager->browser()->GetClient();
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 {
gfx::Rect bounds;
manager->browser()->GetWebContents()->GetView()->GetContainerBounds(&bounds);
screen_point = bounds.origin();
screen_point.Offset(manager->params().x, manager->params().y);
content::RenderWidgetHostView* view =
manager->browser()->GetWebContents()->GetRenderWidgetHostView();
event = view->GetLastMouseDown();
}
if (!menu_delegate_.get())
menu_delegate_.reset(new CefMenuDelegate);
// Create a menu based on the model.
menu_.reset(new MenuGtk(menu_delegate_.get(), manager->model()));
gfx::Rect bounds;
manager->browser()->GetWebContents()->GetView()->GetContainerBounds(&bounds);
gfx::Point point = bounds.origin();
point.Offset(manager->params().x, manager->params().y);
content::RenderWidgetHostView* view =
manager->browser()->GetWebContents()->GetRenderWidgetHostView();
GdkEventButton* event = view->GetLastMouseDown();
uint32_t triggering_event_time = event ? event->time : GDK_CURRENT_TIME;
// Show the menu. Execution will continue asynchronously.
menu_->PopupAsContext(point, triggering_event_time);
menu_->PopupAsContext(screen_point, triggering_event_time);
return true;
}

View File

@ -14,6 +14,7 @@
class CefMenuCreatorRunnerGtk: public CefMenuCreator::Runner {
public:
CefMenuCreatorRunnerGtk();
virtual ~CefMenuCreatorRunnerGtk();
// CefMemoryManager::Runner methods.
virtual bool RunContextMenu(CefMenuCreator* manager) OVERRIDE;

View File

@ -192,10 +192,10 @@ void CefRenderWidgetHostViewOSR::UpdateCursor(const WebCursor& cursor) {
HCURSOR hCursor = web_cursor.GetCursor((HINSTANCE)hModule);
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
browser_impl_->GetBrowser(), hCursor);
#elif defined(OS_MACOSX)
#elif defined(OS_MACOSX) || defined(TOOLKIT_GTK)
// cursor is const, and GetNativeCursor is not
WebCursor web_cursor = cursor;
NSCursor* native_cursor = web_cursor.GetNativeCursor();
CefCursorHandle native_cursor = web_cursor.GetNativeCursor();
browser_impl_->GetClient()->GetRenderHandler()->OnCursorChange(
browser_impl_->GetBrowser(), native_cursor);
#else
@ -683,3 +683,14 @@ bool CefRenderWidgetHostViewOSR::IsSpeaking() const {
void CefRenderWidgetHostViewOSR::StopSpeaking() {
}
#endif // defined(OS_MACOSX)
#if defined(TOOLKIT_GTK)
GdkEventButton* CefRenderWidgetHostViewOSR::GetLastMouseDown() {
return NULL;
}
gfx::NativeView CefRenderWidgetHostViewOSR::BuildInputMethodsGtkMenu() {
return NULL;
}
#endif // defined(TOOLKIT_GTK)

View File

@ -93,14 +93,16 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual void WindowFrameChanged() OVERRIDE;
virtual void ShowDefinitionForSelection() OVERRIDE;
virtual bool SupportsSpeech() const OVERRIDE;
virtual void SpeakSelection() OVERRIDE;
virtual bool IsSpeaking() const OVERRIDE;
virtual void StopSpeaking() OVERRIDE;
#endif // defined(OS_MACOSX)
#if defined(TOOLKIT_GTK)
virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
#endif // defined(TOOLKIT_GTK)
// RenderWidgetHostViewPort methods.
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,

View File

@ -2,7 +2,12 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
// This value is defined in build/common.gypi and must be undefined here
// in order for gtkglext to compile.
#undef GTK_DISABLE_SINGLE_INCLUDES
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
@ -11,7 +16,9 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_runnable.h"
#include "cefclient/cefclient_osr_widget_gtk.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
#include "cefclient/scheme_test.h"
#include "cefclient/string_util.h"
@ -20,6 +27,15 @@ char szWorkingDir[512]; // The current working directory
// The global ClientHandler reference.
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;
void destroy(GtkWidget* widget, gpointer data) {
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
}
@ -248,6 +264,9 @@ int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
// Perform gtkglext initialization required by the OSR example.
gtk_gl_init(&argc, &argv);
// Parse command line arguments.
AppInitCommandLine(argc, argv);
@ -324,7 +343,19 @@ int main(int argc, char* argv[]) {
CefWindowInfo window_info;
CefBrowserSettings browserSettings;
if (AppIsOffScreenRenderingEnabled()) {
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
bool transparent =
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
CefRefPtr<OSRWindow> osr_window =
OSRWindow::Create(&g_main_browser_provider, transparent, vbox);
window_info.SetAsOffScreen(osr_window->GetWindowHandle());
window_info.SetTransparentPainting(transparent);
g_handler->SetOSRHandler(osr_window.get());
} else {
window_info.SetAsChild(vbox);
}
CefBrowserHost::CreateBrowserSync(
window_info, g_handler.get(),

View File

@ -0,0 +1,491 @@
// Copyright (c) 2013 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_gtk.h"
// This value is defined in build/common.gypi and must be undefined here
// in order for gtkglext to compile.
#undef GTK_DISABLE_SINGLE_INCLUDES
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include "include/cef_runnable.h"
#include "cefclient/util.h"
namespace {
gint glarea_size_allocation(GtkWidget* widget,
GtkAllocation* allocation,
OSRWindow* window) {
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
host->WasResized();
return TRUE;
}
int get_cef_state_modifiers(guint state) {
int modifiers = 0;
if (state & GDK_SHIFT_MASK)
modifiers |= EVENTFLAG_SHIFT_DOWN;
if (state & GDK_LOCK_MASK)
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
if (state & GDK_CONTROL_MASK)
modifiers |= EVENTFLAG_CONTROL_DOWN;
if (state & GDK_MOD1_MASK)
modifiers |= EVENTFLAG_ALT_DOWN;
if (state & GDK_BUTTON1_MASK)
modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON;
if (state & GDK_BUTTON2_MASK)
modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if (state & GDK_BUTTON3_MASK)
modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON;
return modifiers;
}
gint glarea_click_event(GtkWidget* widget,
GdkEventButton* event,
OSRWindow* window) {
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
CefBrowserHost::MouseButtonType button_type = MBT_LEFT;
switch (event->button) {
case 1:
break;
case 2:
button_type = MBT_MIDDLE;
break;
case 3:
button_type = MBT_RIGHT;
break;
default:
// Other mouse buttons are not handled here.
return FALSE;
}
CefMouseEvent mouse_event;
mouse_event.x = event->x;
mouse_event.y = event->y;
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = get_cef_state_modifiers(event->state);
bool mouse_up = (event->type == GDK_BUTTON_RELEASE);
if (!mouse_up)
gtk_widget_grab_focus(widget);
int click_count = 1;
switch (event->type) {
case GDK_2BUTTON_PRESS:
click_count = 2;
break;
case GDK_3BUTTON_PRESS:
click_count = 3;
break;
default:
break;
}
host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count);
return TRUE;
}
gint glarea_move_event(GtkWidget* widget,
GdkEventMotion* event,
OSRWindow* window) {
gint x, y;
GdkModifierType state;
if (event->is_hint) {
gdk_window_get_pointer(event->window, &x, &y, &state);
} else {
x = (gint)event->x;
y = (gint)event->y;
state = (GdkModifierType)event->state;
}
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
CefMouseEvent mouse_event;
mouse_event.x = x;
mouse_event.y = y;
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = get_cef_state_modifiers(state);
bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
host->SendMouseMoveEvent(mouse_event, mouse_leave);
return TRUE;
}
gint glarea_scroll_event(GtkWidget* widget,
GdkEventScroll* event,
OSRWindow* window) {
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
CefMouseEvent mouse_event;
mouse_event.x = event->x;
mouse_event.y = event->y;
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
mouse_event.modifiers = get_cef_state_modifiers(event->state);
static const int scrollbarPixelsPerGtkTick = 40;
int deltaX = 0;
int deltaY = 0;
switch (event->direction) {
case GDK_SCROLL_UP:
deltaY = scrollbarPixelsPerGtkTick;
break;
case GDK_SCROLL_DOWN:
deltaY = -scrollbarPixelsPerGtkTick;
break;
case GDK_SCROLL_LEFT:
deltaX = scrollbarPixelsPerGtkTick;
break;
case GDK_SCROLL_RIGHT:
deltaX = -scrollbarPixelsPerGtkTick;
break;
}
host->SendMouseWheelEvent(mouse_event, deltaX, deltaY);
return TRUE;
}
gint glarea_key_event(GtkWidget* widget,
GdkEventKey* event,
OSRWindow* window) {
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
CefKeyEvent key_event;
key_event.native_key_code = event->keyval;
key_event.modifiers = get_cef_state_modifiers(event->state);
if (event->type == GDK_KEY_PRESS) {
key_event.type = KEYEVENT_RAWKEYDOWN;
host->SendKeyEvent(key_event);
} else {
// Need to send both KEYUP and CHAR events.
key_event.type = KEYEVENT_KEYUP;
host->SendKeyEvent(key_event);
key_event.type = KEYEVENT_CHAR;
host->SendKeyEvent(key_event);
}
return TRUE;
}
gint glarea_focus_event(GtkWidget* widget,
GdkEventFocus* event,
OSRWindow* window) {
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
host->SendFocusEvent(event->in == TRUE);
return TRUE;
}
void widget_get_rect_in_screen(GtkWidget* widget, GdkRectangle* r) {
gint x, y, w, h;
GdkRectangle extents;
GdkWindow* window = gtk_widget_get_parent_window(widget);
// Get parent's left-top screen coordinates.
gdk_window_get_root_origin(window, &x, &y);
// Get parent's width and height.
gdk_drawable_get_size(window, &w, &h);
// Get parent's extents including decorations.
gdk_window_get_frame_extents(window, &extents);
// X and Y calculations assume that left, right and bottom border sizes are
// all the same.
const gint border = (extents.width - w) / 2;
r->x = x + border + widget->allocation.x;
r->y = y + (extents.height - h) - border + widget->allocation.y;
r->width = widget->allocation.width;
r->height = widget->allocation.height;
}
class ScopedGLContext {
public:
ScopedGLContext(GtkWidget* widget, bool swap_buffers)
: swap_buffers_(swap_buffers) {
GdkGLContext* glcontext = gtk_widget_get_gl_context(widget);
gldrawable_ = gtk_widget_get_gl_drawable(widget);
is_valid_ = gdk_gl_drawable_gl_begin(gldrawable_, glcontext);
}
virtual ~ScopedGLContext() {
if (is_valid_) {
gdk_gl_drawable_gl_end(gldrawable_);
if(swap_buffers_) {
if (gdk_gl_drawable_is_double_buffered(gldrawable_))
gdk_gl_drawable_swap_buffers(gldrawable_);
else
glFlush();
}
}
}
bool IsValid() const { return is_valid_; }
private:
bool swap_buffers_;
GdkGLContext* glcontext_;
GdkGLDrawable* gldrawable_;
bool is_valid_;
};
} // namespace
// static
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView) {
ASSERT(browser_provider);
if (!browser_provider)
return NULL;
return new OSRWindow(browser_provider, transparent, parentView);
}
// static
CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get());
}
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
// Disconnect all signal handlers that reference |this|.
g_signal_handlers_disconnect_by_data(glarea_, this);
DisableGL();
}
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
if (!glarea_)
return false;
// The simulated screen and view rectangle are the same. This is necessary
// for popup menus to be located and sized inside the view.
rect.x = rect.y = 0;
rect.width = glarea_->allocation.width;
rect.height = glarea_->allocation.height;
return true;
}
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
GdkRectangle screen_rect;
widget_get_rect_in_screen(glarea_, &screen_rect);
screenX = screen_rect.x + viewX;
screenY = screen_rect.y + viewY;
return true;
}
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
if (!show) {
CefRect dirty_rect = renderer_.popup_rect();
renderer_.ClearPopupRects();
browser->GetHost()->Invalidate(dirty_rect, PET_VIEW);
}
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) {
if (painting_popup_) {
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
return;
}
if (!gl_enabled_)
EnableGL();
ScopedGLContext scoped_gl_context(glarea_, true);
if (!scoped_gl_context.IsValid())
return;
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
painting_popup_ = true;
CefRect client_popup_rect(0, 0,
renderer_.popup_rect().width,
renderer_.popup_rect().height);
browser->GetHost()->Invalidate(client_popup_rect, PET_POPUP);
painting_popup_ = false;
}
renderer_.Render();
}
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor) {
GtkWidget* window = gtk_widget_get_toplevel(glarea_);
GdkWindow* gdk_window = gtk_widget_get_window(window);
if (cursor->type == GDK_LAST_CURSOR)
cursor = NULL;
gdk_window_set_cursor(gdk_window, cursor);
}
void OSRWindow::Invalidate() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Invalidate));
return;
}
// Don't post another task if the previous task is still pending.
if (render_task_pending_)
return;
render_task_pending_ = true;
// Render at 30fps.
static const int kRenderDelay = 1000 / 30;
CefPostDelayedTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Render),
kRenderDelay);
}
bool OSRWindow::IsOverPopupWidget(int x, int y) const {
const CefRect& rc = renderer_.popup_rect();
int popup_right = rc.x + rc.width;
int popup_bottom = rc.y + rc.height;
return (x >= rc.x) && (x < popup_right) &&
(y >= rc.y) && (y < popup_bottom);
}
int OSRWindow::GetPopupXOffset() const {
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
}
int OSRWindow::GetPopupYOffset() const {
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
}
void OSRWindow::ApplyPopupOffset(int& x, int& y) const {
if (IsOverPopupWidget(x, y)) {
x += GetPopupXOffset();
y += GetPopupYOffset();
}
}
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView)
: renderer_(transparent),
browser_provider_(browser_provider),
gl_enabled_(false),
painting_popup_(false),
render_task_pending_(false) {
glarea_ = gtk_drawing_area_new();
ASSERT(glarea_);
GdkGLConfig* glconfig = gdk_gl_config_new_by_mode(
static_cast<GdkGLConfigMode>(GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE));
ASSERT(glconfig);
gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE,
GDK_GL_RGBA_TYPE);
gtk_widget_set_can_focus(glarea_, TRUE);
g_signal_connect(G_OBJECT(glarea_), "size_allocate",
G_CALLBACK(glarea_size_allocation), this);
gtk_widget_set_events(glarea_,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_SCROLL_MASK |
GDK_FOCUS_CHANGE_MASK);
g_signal_connect(G_OBJECT(glarea_), "button_press_event",
G_CALLBACK(glarea_click_event), this);
g_signal_connect(G_OBJECT(glarea_), "button_release_event",
G_CALLBACK(glarea_click_event), this);
g_signal_connect(G_OBJECT(glarea_), "key_press_event",
G_CALLBACK(glarea_key_event), this);
g_signal_connect(G_OBJECT(glarea_), "key_release_event",
G_CALLBACK(glarea_key_event), this);
g_signal_connect(G_OBJECT(glarea_), "enter_notify_event",
G_CALLBACK(glarea_move_event), this);
g_signal_connect(G_OBJECT(glarea_), "leave_notify_event",
G_CALLBACK(glarea_move_event), this);
g_signal_connect(G_OBJECT(glarea_), "motion_notify_event",
G_CALLBACK(glarea_move_event), this);
g_signal_connect(G_OBJECT(glarea_), "scroll_event",
G_CALLBACK(glarea_scroll_event), this);
g_signal_connect(G_OBJECT(glarea_), "focus_in_event",
G_CALLBACK(glarea_focus_event), this);
g_signal_connect(G_OBJECT(glarea_), "focus_out_event",
G_CALLBACK(glarea_focus_event), this);
gtk_container_add(GTK_CONTAINER(parentView), glarea_);
}
OSRWindow::~OSRWindow() {
}
void OSRWindow::Render() {
ASSERT(CefCurrentlyOn(TID_UI));
if (render_task_pending_)
render_task_pending_ = false;
if (!gl_enabled_)
EnableGL();
ScopedGLContext scoped_gl_context(glarea_, true);
if (!scoped_gl_context.IsValid())
return;
renderer_.Render();
}
void OSRWindow::EnableGL() {
ASSERT(CefCurrentlyOn(TID_UI));
if (gl_enabled_)
return;
ScopedGLContext scoped_gl_context(glarea_, false);
if (!scoped_gl_context.IsValid())
return;
renderer_.Initialize();
gl_enabled_ = true;
}
void OSRWindow::DisableGL() {
ASSERT(CefCurrentlyOn(TID_UI));
if (!gl_enabled_)
return;
ScopedGLContext scoped_gl_context(glarea_, false);
if (!scoped_gl_context.IsValid())
return;
renderer_.Cleanup();
gl_enabled_ = false;
}

View File

@ -0,0 +1,90 @@
// Copyright (c) 2013 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_GTK_H_
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/client_handler.h"
#include "cefclient/osrenderer.h"
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public ClientHandler::RenderHandler {
public:
// Create a new OSRWindow instance. |browser_provider| must outlive this
// object.
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView);
static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
CefWindowHandle GetWindowHandle() const {
return glarea_;
}
CefRefPtr<CefBrowserHost> GetBrowserHost() const {
return browser_provider_->GetBrowser()->GetHost();
}
// ClientHandler::RenderHandler methods
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
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 Invalidate();
bool IsOverPopupWidget(int x, int y) const;
int GetPopupXOffset() const;
int GetPopupYOffset() const;
void ApplyPopupOffset(int& x, int& y) const;
private:
OSRWindow(OSRBrowserProvider* browser_provider,
bool transparent,
CefWindowHandle parentView);
virtual ~OSRWindow();
void Render();
void EnableGL();
void DisableGL();
ClientOSRenderer renderer_;
OSRBrowserProvider* browser_provider_;
CefWindowHandle glarea_;
bool gl_enabled_;
bool painting_popup_;
bool render_task_pending_;
IMPLEMENT_REFCOUNTING(OSRWindow);
};
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_

View File

@ -9,6 +9,9 @@
#include <gl/glu.h>
#elif defined(OS_MACOSX)
#include <OpenGL/gl.h>
#elif defined(OS_LINUX)
#include <GL/gl.h>
#include <GL/glu.h>
#else
#error Platform is not supported.
#endif

View File

@ -52,7 +52,7 @@
</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>
<input id='editbox' type='text' value='' size="5"></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>

View File

@ -16,6 +16,8 @@
#if defined(OS_MACOSX)
#include "tests/unittests/os_rendering_unittest_mac.h"
#elif defined(OS_LINUX)
#include <X11/keysym.h>
#elif defined(OS_WIN)
// Required for resource_util_win, which uses this as an extern
HINSTANCE hInst = ::GetModuleHandle(NULL);
@ -35,7 +37,7 @@ const int kOsrWidth = 600;
const int kOsrHeight = 400;
// precomputed bounding client rects for html elements (h1 and li).
#if defined(OS_WIN)
#if defined(OS_WIN) || defined(OS_LINUX)
const CefRect kExpectedRectLI[] = {
CefRect(8, 8, 567, 74), // LI00
CefRect(27, 103, 548, 20), // LI01
@ -69,26 +71,34 @@ const CefRect kExpectedRectLI[] = {
// bounding client rects for edit box and navigate button
#if defined(OS_WIN)
const CefRect kEditBoxRect(412, 245, 153, 22);
const CefRect kEditBoxRect(412, 245, 60, 22);
const CefRect kNavigateButtonRect(360, 271, 140, 22);
const CefRect kSelectRect(467, 22, 75, 20);
const CefRect kExpandedSelectRect(467, 42, 81, 322);
const int kDefaultVerticalScrollbarWidth = 17;
const int kVerticalScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
const int kHorizontalScrollbarWidth = GetSystemMetrics(SM_CXHSCROLL);
#elif defined(OS_MACOSX)
const CefRect kEditBoxRect(429, 228, 129, 25);
const CefRect kEditBoxRect(429, 228, 60, 25);
const CefRect kNavigateButtonRect(375, 251, 138, 28);
const CefRect kSelectRect(461, 21, 87, 26);
const CefRect kExpandedSelectRect(467, 42, 80, 262);
#elif defined(OS_LINUX)
const CefRect kEditBoxRect(434, 246, 60, 20);
const CefRect kNavigateButtonRect(380, 271, 140, 22);
const CefRect kSelectRect(467, 22, 75, 20);
const CefRect kExpandedSelectRect(467, 42, 79, 322);
const int kDefaultVerticalScrollbarWidth = 14;
const int kVerticalScrollbarWidth = 14;
const int kHorizontalScrollbarWidth = 14;
#else
#error "Unsupported platform"
#endif // defined(OS_WIN)
// adjusted expected rect regarding system vertical scrollbar width
CefRect ExpectedRect(int index) {
#if defined(OS_WIN)
#if defined(OS_WIN) || defined(OS_LINUX)
// this is the scrollbar width for all the kExpectedRectLI
const int kDefaultVerticalScrollbarWidth = 17;
if (kDefaultVerticalScrollbarWidth == kVerticalScrollbarWidth)
return kExpectedRectLI[index];
@ -106,12 +116,21 @@ CefRect ExpectedRect(int index) {
// word to be written into edit box
const char kKeyTestWord[] = "done";
#if defined(OS_MACOSX)
const ui::KeyboardCode kKeyTestCodes[] = {
ui::VKEY_D,
ui::VKEY_O,
ui::VKEY_N,
ui::VKEY_E
};
#elif defined(OS_LINUX)
const unsigned int kKeyTestCodes[] = {
XK_d,
XK_o,
XK_n,
XK_e
};
#endif
// width for the icon that appear on the screen when pressing
// middle mouse button
@ -210,10 +229,13 @@ class OSRTestHandler : public TestHandler,
return;
switch(test_type_) {
case OSR_TEST_KEY_EVENTS:
EXPECT_EQ(frame->GetURL(), std::string(kTestUrl) + "?k=" + kKeyTestWord);
case OSR_TEST_KEY_EVENTS: {
const std::string& expected_url =
std::string(kTestUrl) + "?k=" + kKeyTestWord;
EXPECT_STREQ(expected_url.c_str(),
frame->GetURL().ToString().c_str());
DestroySucceededTestSoon();
break;
} break;
default:
// Intentionally left blank
break;
@ -544,6 +566,8 @@ class OSRTestHandler : public TestHandler,
event.windows_key_code = VkCode;
#elif defined(OS_MACOSX)
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
#elif defined(OS_LINUX)
event.native_key_code = kKeyTestCodes[i];
#else
NOTREACHED();
#endif
@ -553,6 +577,8 @@ class OSRTestHandler : public TestHandler,
event.windows_key_code = kKeyTestWord[i];
#elif defined(OS_MACOSX)
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
#elif defined(OS_LINUX)
event.native_key_code = kKeyTestCodes[i];
#endif
event.type = KEYEVENT_CHAR;
browser->GetHost()->SendKeyEvent(event);
@ -562,6 +588,8 @@ class OSRTestHandler : public TestHandler,
event.native_key_code |= 0xC0000000;
#elif defined(OS_MACOSX)
osr_unittests::GetKeyEvent(event, kKeyTestCodes[i], 0);
#elif defined(OS_LINUX)
event.native_key_code = kKeyTestCodes[i];
#endif
event.type = KEYEVENT_KEYUP;
browser->GetHost()->SendKeyEvent(event);
@ -623,6 +651,11 @@ class OSRTestHandler : public TestHandler,
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
kOsrWidth, kOsrHeight));
DestroySucceededTestSoon();
#elif defined(OS_LINUX)
EXPECT_EQ(dirtyRects.size(), 1U);
EXPECT_EQ(dirtyRects[0], CefRect(0, 0,
kOsrWidth, kOsrHeight));
DestroySucceededTestSoon();
#else
#error "Unsupported platform"
#endif // defined(OS_WIN)
@ -676,6 +709,8 @@ class OSRTestHandler : public TestHandler,
event.windows_key_code = VkCode;
#elif defined(OS_MACOSX)
osr_unittests::GetKeyEvent(event, ui::VKEY_ESCAPE, 0);
#elif defined(OS_LINUX)
event.native_key_code = XK_Escape;
#else
#error "Unsupported platform"
#endif // defined(OS_WIN)
@ -729,7 +764,7 @@ class OSRTestHandler : public TestHandler,
1,
kExpandedSelectRect.width - 3,
kExpandedSelectRect.height - 2));
#elif defined(OS_MACOSX)
#elif defined(OS_MACOSX) || defined(OS_LINUX)
EXPECT_EQ(dirtyRects[0],
CefRect(1,
0,
@ -759,7 +794,7 @@ class OSRTestHandler : public TestHandler,
virtual bool OnTooltip(CefRefPtr<CefBrowser> browser,
CefString& text) OVERRIDE {
if (test_type_ == OSR_TEST_TOOLTIP && started()) {
EXPECT_EQ(text, "EXPECTED_TOOLTIP");
EXPECT_STREQ("EXPECTED_TOOLTIP", text.ToString().c_str());
DestroySucceededTestSoon();
}
return false;
@ -794,6 +829,8 @@ class OSRTestHandler : public TestHandler,
windowInfo.SetAsOffScreen(osr_unittests::GetFakeView());
else
windowInfo.SetAsOffScreen(NULL);
#elif defined(OS_LINUX)
windowInfo.SetAsOffScreen(NULL);
#else
#error "Unsupported platform"
#endif

View File

@ -315,7 +315,8 @@
'variables': {
# gtk requires gmodule, but it does not list it as a dependency
# in some misconfigured systems.
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0',
# gtkglext is required by the cefclient OSR example.
'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0 gtkglext-1.0',
},
'direct_dependent_settings': {
'cflags': [