XWalk WebView patchset, README and LICENSE files. 23/9923/1 master
authorDominik Röttsches <dominik.rottsches@intel.com>
Mon, 12 Aug 2013 13:35:51 +0000 (16:35 +0300)
committerDominik Röttsches <dominik.rottsches@intel.com>
Wed, 11 Sep 2013 09:29:11 +0000 (12:29 +0300)
Change-Id: I602ac0dfc2dbff7686d94baad4dc8fecf321a001

35 files changed:
LICENSE.txt [new file with mode: 0644]
README.txt [new file with mode: 0644]
patchset/0001-Link-content-shell-against-EFL.patch [new file with mode: 0644]
patchset/0002-Adding-RenderWidgetHostViewEfl.patch [new file with mode: 0644]
patchset/0003-Compiles-without-GTK.patch [new file with mode: 0644]
patchset/0004-Event-handling-implementation.patch [new file with mode: 0644]
patchset/0005-Implement-efl-webview-library-and-example-launcher.patch [new file with mode: 0644]
patchset/0006-Add-message_pump_xwalk-for-embedder.patch [new file with mode: 0644]
patchset/0007-XWalk-must-set-ContentClient-for-user-agent.patch [new file with mode: 0644]
patchset/0008-Add-reload-button.patch [new file with mode: 0644]
patchset/0009-Implement-focus-handling-of-delegate.patch [new file with mode: 0644]
patchset/0010-Introducing-C-API-for-EFL-Web-View.patch [new file with mode: 0644]
patchset/0011-Cleanup-example.-Call-Xlib-directly.-Add-URL-entry.patch [new file with mode: 0644]
patchset/0012-WebView-re-factoring-no-dep-to-elm-memory-management.patch [new file with mode: 0644]
patchset/0013-Remove-view-from-the-container-when-rwhv-is-deleted.patch [new file with mode: 0644]
patchset/0014-Use-WebContentsViewDelegate-GetNativeView-instead-of.patch [new file with mode: 0644]
patchset/0015-Load-progress-api.patch [new file with mode: 0644]
patchset/0016-Update-page-title-API.patch [new file with mode: 0644]
patchset/0017-URL-changed-API.patch [new file with mode: 0644]
patchset/0018-Add-documentation-to-xwalk-view-public-API.patch [new file with mode: 0644]
patchset/0019-Renaming.-Fixed-layout-while-loading-from-address-ba.patch [new file with mode: 0644]
patchset/0020-UTF8-window-titles.patch [new file with mode: 0644]
patchset/0021-Add-loading-indication-API-and-use-it-in-example-app.patch [new file with mode: 0644]
patchset/0022-Remove-elm-dependency-from-preserve_window_efl.patch [new file with mode: 0644]
patchset/0023-Fix-the-build-after-c109537.patch [new file with mode: 0644]
patchset/0024-Fixed-content-shell-content-rendering-crash-on-exit..patch [new file with mode: 0644]
patchset/0025-Fix-key-events.patch [new file with mode: 0644]
patchset/0026-Example-app-code-clean-up.patch [new file with mode: 0644]
patchset/0027-Always-build-the-efl_webview-target-as-a-shared-libr.patch [new file with mode: 0644]
patchset/0028-Remove-a-few-unused-variables-from-the-efl_webview-g.patch [new file with mode: 0644]
patchset/0029-packaging-Add-a-.spec-file-for-crosswalk-webview.patch [new file with mode: 0644]
patchset/0030-Remove-outdated-TODO.patch [new file with mode: 0644]
patchset/0031-Be-more-flexible-in-the-way-we-look-for-efl_process.patch [new file with mode: 0644]
patchset/0032-Obviate-device-scale-factor-problem.patch [new file with mode: 0644]
patchset/0033-Workaround-for-X-window-update-delay.patch [new file with mode: 0644]

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..29797cd
--- /dev/null
@@ -0,0 +1,2 @@
+Additional files created by Intel are licensed under the BSD-style license that Chromium uses (see LICENSE in the
+Chromium tree), with the exception of efl_webview/lib/web_runtime_context.cc which is licensed under LGPL 2.1.
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..f8d42d3
--- /dev/null
@@ -0,0 +1,94 @@
+Intel's Chromium EFL WebView Release
+====================================
+
+Version 0.1, 08/2013
+
+1) Introduction
+
+Today we're releasing a patchset on top of Chromium 28.0.1500.36 that enables you to use Chromium as an Evas_Object inside
+EFL applications.
+
+2) License
+
+Please see LICENSE.txt.
+
+3) Architectural Overview
+
+The EFL WebView is based on Chromium's WebContentView architecture. In the Chromium codebase, 4 implementations of the
+WebContentView class exist: Win, Mac, Gtk+, Aura. It is the basic abstraction of a UI toolkit-independent control that
+renders web pages. Our patch set adds an additional implementation that uses and complies with concepts from the EFL
+toolkit. So, in addition to Chromium's implementations we added WebContentsViewEfl. The WebContentsView architecture
+requires a related container, for our case this is RenderWidgetHostViewEfl.
+
+Additional integrations with EFL were required, such as implementing a message pump based on the EFL event loop (see
+efl_webview/lib/message_pump_xwalk.h), and modifying Chromium's gyp-based build files to link against the EFL toolkit.
+
+The EFL WebView was designed as a library that complies with EFL concepts. As such, when developing an application based
+on the Chromium EFL WebView, you can just link against our new library and use the provided API header.
+
+The EFL WebView provides an executable launcher that runs a Chromium renderer process which is used as soon as the EFL
+WebView is used in an EFL application.
+
+3) Instructions
+
+  1. Check out Chromium using git or svn equivalent to the following revision:
+     http://src.chromium.org/svn/branches/1500/src@204086
+     (Instructions at http://dev.chromium.org/developers/how-tos/get-the-code )
+  2. Make sure you can build Chromium from upstream, ideally using make, not ninja.
+  3. Apply the files from the patchset/* directory:
+     $ cd ${CHROMIUM_CHECKOUT_DIR}/src
+     $ git apply ${WEBVIEW_DELIVERY_DIR}/patchset/*.patch
+  4. In order to build the example code, run
+       $ make efl_webview_example
+  5. In the out/Debug directory, run
+       $ ./efl_webview_example
+     to run the example application.
+
+4) API
+
+After applying the patch set, the API header, including Doxygen-style documentation is found in:
+efl_webview/public/*, especially efl_webview/public/xwalk_view.h
+
+5) Example application
+
+The documented code for the example application that is built in step 4 of the build instructions is found in
+efl_webview/examples/main.cc
+
+6) Known Issues
+
+- Lifetime of the host application threads:
+  In Chromium architecture, the UI process spins a number of support threads whose purpose is to serve requests coming
+  from the renderer process. As soon as the xwalk_view is used, these threads are created and keep running for the
+  lifetime of the application that uses the control. This lifetime could be optimized so that they are stopped when the
+  control is not used any more.
+- EFL event integration
+  Care was taken when it comes to implementing full keyboard and mouse event support. However, there might be remaining
+  issues, especially with regards to touch events.
+- EFL theming integration
+  Integration with Edje to control the rendering of form controls still needs to be developed. As of now, Chromium's
+  default theming is always used.
+- Video playback support
+  Chromium uses its own libffmpegsumo.so library for video playback. Currently, it always expects this library to be
+  located in the same directory as the executable being run.
+- X window update on Tizen 2.1
+  On Tizen 2.1 mobile devices there is an issue with updating xwalk_view X window after GPU process swaps the buffers:
+  X window is not updated in time, heavily affecting the user experience. At the moment, we have a temporary work around
+  (forced X window update) however the correct solution should be found in future.
+- OpenGL backends
+  By default, the Chromium code first tries to load a Desktop (GLX) implementation for it to use for accelerated
+  compositing. While this works fine on the desktop, Tizen 2.1 Mobile only provides an EGL implementation. This means
+  that in order to properly run applications on a device it is necessary to either pass "--use-gl=egl" to them or adjust
+  the GL backend loading code for EGL to be preferred.
+  The Tizen 2.1 emulator's EGL implementation; using Chromium's libosmesa.so and passing "--use-gl=osmesa" to
+  applications is advised.
+
+7) Authors
+
+People who have contributed to this release, in alphabetical order:
+
+Bhaumik, Rijubrata <rijubrata.bhaumik@intel.com>
+Hwang, Dongseong <dongseong.hwang@intel.com>
+Kubo Da Costa, Raphael <raphael.kubo.da.costa@intel.com>
+Pozdnyakov, Mikhail <mikhail.pozdnyakov@intel.com>
+Röttsches, Dominik <dominik.rottsches@intel.com>
+Shalamov, Alexander <alexander.shalamov@intel.com>
diff --git a/patchset/0001-Link-content-shell-against-EFL.patch b/patchset/0001-Link-content-shell-against-EFL.patch
new file mode 100644 (file)
index 0000000..a03a303
--- /dev/null
@@ -0,0 +1,1147 @@
+From d34de9b3c07bfaa3155deecf1155a5b6cd2af493 Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Tue, 11 Jun 2013 14:32:49 +0300
+Subject: [PATCH 01/33] Link content-shell against EFL.
+
+Define TOOLKIT_EFL.
+gyp: Define `toolkit_uses_efl'.
+Add an inital implementation of WebViewContentsEfl.
+Add efl_util.{cc,h} to initialize and shut down the EFL.
+Add MessagePumpEfl.
+Build ShellEfl.
+---
+ base/base.gyp                                      |  16 ++
+ base/message_loop.h                                |   2 +
+ base/message_pump_efl.cc                           | 174 ++++++++++++++
+ base/message_pump_efl.h                            |  66 +++++
+ build/build_config.h                               |   1 +
+ build/common.gypi                                  |   4 +
+ build/linux/system.gyp                             |  21 ++
+ content/browser/browser_main_loop.cc               |  11 +
+ content/browser/power_save_blocker_x11.cc          |   4 +-
+ .../browser/web_contents/web_contents_view_efl.cc  | 265 +++++++++++++++++++++
+ .../browser/web_contents/web_contents_view_efl.h   |  97 ++++++++
+ content/content_browser.gypi                       |  11 +
+ content/content_shell.gypi                         |  10 +
+ content/shell/shell.h                              |  16 +-
+ content/shell/shell_efl.cc                         | 110 +++++++++
+ ui/gfx/efl_util.cc                                 |  33 +++
+ ui/gfx/efl_util.h                                  |  20 ++
+ ui/ui.gyp                                          |   9 +
+ 18 files changed, 867 insertions(+), 3 deletions(-)
+ create mode 100644 base/message_pump_efl.cc
+ create mode 100644 base/message_pump_efl.h
+ create mode 100644 content/browser/web_contents/web_contents_view_efl.cc
+ create mode 100644 content/browser/web_contents/web_contents_view_efl.h
+ create mode 100644 content/shell/shell_efl.cc
+ create mode 100644 ui/gfx/efl_util.cc
+ create mode 100644 ui/gfx/efl_util.h
+
+diff --git a/base/base.gyp b/base/base.gyp
+index 8b3ebac..b9e7e36 100644
+--- a/base/base.gyp
++++ b/base/base.gyp
+@@ -79,6 +79,22 @@
+               ['exclude', '_nss\\.cc$'],
+             ],
+         }],
++        ['toolkit_uses_efl==1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++          'export_dependent_settings': [
++            '../build/linux/system.gyp:efl',
++          ],
++          'sources': [
++            'message_pump_efl.cc',
++            'message_pump_efl.h',
++          ],
++          'sources/': [
++            ['exclude', 'message_pump_gtk.cc'],
++            ['exclude', 'message_pump_gtk.h'],
++          ],
++        }],
+         ['use_x11==1', {
+           'dependencies': [
+             '../build/linux/system.gyp:x11',
+diff --git a/base/message_loop.h b/base/message_loop.h
+index f3ad3a5..8a1cc06 100644
+--- a/base/message_loop.h
++++ b/base/message_loop.h
+@@ -36,6 +36,8 @@
+ #include "base/message_pump_aurax11.h"
+ #elif defined(USE_OZONE) && !defined(OS_NACL)
+ #include "base/message_pump_ozone.h"
++#elif defined(TOOLKIT_EFL)
++#include "base/message_pump_efl.h"
+ #else
+ #include "base/message_pump_gtk.h"
+ #endif
+diff --git a/base/message_pump_efl.cc b/base/message_pump_efl.cc
+new file mode 100644
+index 0000000..cdfe740
+--- /dev/null
++++ b/base/message_pump_efl.cc
+@@ -0,0 +1,174 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "base/message_pump_efl.h"
++
++#include <Ecore.h>
++#include <Ecore_X.h>
++#include <X11/Xlib.h>
++
++#include "base/debug/trace_event.h"
++#include "base/logging.h"
++#include "base/posix/eintr_wrapper.h"
++#include "base/threading/platform_thread.h"
++
++namespace {
++static const int ecorePipeMessageSize = 1;
++static const char wakupEcorePipeMessage[] = "W";
++
++void WakeUpEvent(void* data, void*, unsigned int) {
++  static_cast<base::MessagePumpEfl*>(data)->HandleDispatch();
++}
++
++}  // namespace
++
++namespace base {
++
++// We may make recursive calls to Run, so we save state that needs to be
++// separate between them in this structure type.
++struct RunState {
++  MessagePump::Delegate* delegate;
++  MessagePumpDispatcher* dispatcher;
++
++  // Used to flag that the current Run() invocation should return ASAP.
++  bool should_quit;
++
++  // Used to count how many Run() invocations are on the stack.
++  int run_depth;
++};
++
++struct MessagePumpEfl::Private {
++  RunState* state_;
++
++  // This is the time when we need to do delayed work.
++  TimeTicks delayed_work_time_;
++
++  // List of observers.
++  ObserverList<MessagePumpObserver> observers_;
++
++  Ecore_Pipe* wakeup_pipe_;
++};
++
++MessagePumpEfl::MessagePumpEfl()
++    : private_(new Private) {
++  private_->state_ = NULL;
++  private_->wakeup_pipe_ = ecore_pipe_add(WakeUpEvent, this);
++}
++
++MessagePumpEfl::~MessagePumpEfl() {
++  ecore_pipe_del(private_->wakeup_pipe_);
++}
++
++void MessagePumpEfl::RunWithDispatcher(Delegate* delegate,
++                                       MessagePumpDispatcher* dispatcher) {
++#ifndef NDEBUG
++  // Make sure we only run this on one thread. X/GTK only has one message pump
++  // so we can only have one UI loop per process.
++  static base::PlatformThreadId thread_id = base::PlatformThread::CurrentId();
++  DCHECK(thread_id == base::PlatformThread::CurrentId()) <<
++      "Running MessagePumpEfl on two different threads; "
++      "this is unsupported by Ecore!";
++#endif
++
++  RunState state;
++  state.delegate = delegate;
++  state.dispatcher = dispatcher;
++  state.should_quit = false;
++  state.run_depth = private_->state_ ? private_->state_->run_depth + 1 : 1;
++
++  RunState* previous_state = private_->state_;
++  private_->state_ = &state;
++
++  bool more_work_is_plausible = true;
++
++  for (;;) {
++    ecore_main_loop_iterate();
++    more_work_is_plausible = false;
++    if (private_->state_->should_quit)
++      break;
++
++    more_work_is_plausible |= private_->state_->delegate->DoWork();
++    if (private_->state_->should_quit)
++      break;
++
++    more_work_is_plausible |=
++      private_->state_->delegate->DoDelayedWork(&private_->delayed_work_time_);
++    if (private_->state_->should_quit)
++      break;
++
++    if (more_work_is_plausible)
++      continue;
++
++    more_work_is_plausible = private_->state_->delegate->DoIdleWork();
++    if (private_->state_->should_quit)
++      break;
++  }
++
++  private_->state_ = previous_state;
++}
++
++void MessagePumpEfl::HandleDispatch() {
++  private_->state_->delegate->DoWork();
++  if (private_->state_->should_quit)
++    return;
++
++  private_->state_->delegate->DoDelayedWork(&private_->delayed_work_time_);
++}
++
++void MessagePumpEfl::AddObserver(MessagePumpObserver* observer) {
++  private_->observers_.AddObserver(observer);
++}
++
++void MessagePumpEfl::RemoveObserver(MessagePumpObserver* observer) {
++  private_->observers_.RemoveObserver(observer);
++}
++
++void MessagePumpEfl::Run(Delegate* delegate) {
++  RunWithDispatcher(delegate, NULL);
++}
++
++void MessagePumpEfl::Quit() {
++  if (private_->state_) {
++    private_->state_->should_quit = true;
++  } else {
++    NOTREACHED() << "Quit called outside Run!";
++  }
++}
++
++void MessagePumpEfl::ScheduleWork() {
++  // This can be called on any thread, so we don't want to touch any state
++  // variables as we would then need locks all over.  This ensures that if
++  // we are sleeping in a poll that we will wake up.
++  if (HANDLE_EINTR(ecore_pipe_write(private_->wakeup_pipe_, wakupEcorePipeMessage, ecorePipeMessageSize)) != 1) {
++    NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
++  }
++}
++
++void MessagePumpEfl::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
++  // We need to wake up the loop in case the poll timeout needs to be
++  // adjusted.  This will cause us to try to do work, but that's ok.
++  private_->delayed_work_time_ = delayed_work_time;
++  ScheduleWork();
++}
++
++MessagePumpDispatcher* MessagePumpEfl::GetDispatcher() {
++  return private_->state_ ? private_->state_->dispatcher : NULL;
++}
++
++ObserverList<MessagePumpObserver>& MessagePumpEfl::observers() {
++  return private_->observers_;
++}
++
++Display* MessagePumpEfl::GetDefaultXDisplay() {
++  static Ecore_X_Display* display = ecore_x_display_get();
++  if (!display) {
++    // Ecore_X has not been initialized, which is a decision we wish to
++    // support, for example for the GPU process.
++    static Display* xdisplay = XOpenDisplay(NULL);
++    return xdisplay;
++  }
++  return static_cast<Display*>(display);
++}
++
++}  // namespace base
+diff --git a/base/message_pump_efl.h b/base/message_pump_efl.h
+new file mode 100644
+index 0000000..7f63188
+--- /dev/null
++++ b/base/message_pump_efl.h
+@@ -0,0 +1,66 @@
++// 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 BASE_MESSAGE_PUMP_EFL_H_
++#define BASE_MESSAGE_PUMP_EFL_H_
++
++#include "base/base_export.h"
++#include "base/event_types.h"
++#include "base/memory/scoped_ptr.h"
++#include "base/message_pump.h"
++#include "base/message_pump_dispatcher.h"
++#include "base/message_pump_observer.h"
++#include "base/observer_list.h"
++#include "base/time.h"
++
++typedef struct _XDisplay Display;
++
++namespace base {
++
++class BASE_EXPORT MessagePumpEfl : public MessagePump {
++public:
++  MessagePumpEfl();
++
++  // Like MessagePump::Run, but events are routed through dispatcher.
++  virtual void RunWithDispatcher(Delegate* delegate,
++                                 MessagePumpDispatcher* dispatcher);
++
++  void HandleDispatch();
++
++  // Adds an Observer, which will start receiving notifications immediately.
++  void AddObserver(MessagePumpObserver* observer);
++
++  // Removes an Observer.  It is safe to call this method while an Observer is
++  // receiving a notification callback.
++  void RemoveObserver(MessagePumpObserver* observer);
++
++  // Overridden from MessagePump:
++  virtual void Run(Delegate* delegate) OVERRIDE;
++  virtual void Quit() OVERRIDE;
++  virtual void ScheduleWork() OVERRIDE;
++  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
++
++  // Returns default X Display.
++  static Display* GetDefaultXDisplay();
++
++protected:
++  virtual ~MessagePumpEfl();
++
++  // Returns the dispatcher for the current run state (|state_->dispatcher|).
++  MessagePumpDispatcher* GetDispatcher();
++
++  ObserverList<MessagePumpObserver>& observers();
++
++private:
++  struct Private;
++  scoped_ptr<Private> private_;
++
++  DISALLOW_COPY_AND_ASSIGN(MessagePumpEfl);
++};
++
++typedef MessagePumpEfl MessagePumpForUI;
++
++}  // namespace base
++
++#endif  // BASE_MESSAGE_PUMP_EFL_H_
+diff --git a/build/build_config.h b/build/build_config.h
+index fef6be5..dd7443e 100644
+--- a/build/build_config.h
++++ b/build/build_config.h
+@@ -33,6 +33,7 @@
+ // Use TOOLKIT_GTK on linux if TOOLKIT_VIEWS isn't defined.
+ #if !defined(TOOLKIT_VIEWS) && defined(USE_X11)
+ #define TOOLKIT_GTK
++#define TOOLKIT_EFL
+ #endif
+ #elif defined(_WIN32)
+ #define OS_WIN 1
+diff --git a/build/common.gypi b/build/common.gypi
+index 6452ffa..9753413 100644
+--- a/build/common.gypi
++++ b/build/common.gypi
+@@ -138,8 +138,10 @@
+           # Set toolkit_uses_gtk for the Chromium browser on Linux.
+           ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_aura==0 and use_ozone==0', {
++            'toolkit_uses_efl%': 1,
+             'toolkit_uses_gtk%': 1,
+           }, {
++            'toolkit_uses_efl%': 0,
+             'toolkit_uses_gtk%': 0,
+           }],
+@@ -188,6 +190,7 @@
+       'host_arch%': '<(host_arch)',
+       'target_arch%': '<(target_arch)',
+       'toolkit_views%': '<(toolkit_views)',
++      'toolkit_uses_efl%': '<(toolkit_uses_efl)',
+       'toolkit_uses_gtk%': '<(toolkit_uses_gtk)',
+       'use_aura%': '<(use_aura)',
+       'use_ash%': '<(use_ash)',
+@@ -751,6 +754,7 @@
+     'os_posix%': '<(os_posix)',
+     'use_glib%': '<(use_glib)',
+     'use_ozone%': '<(use_ozone)',
++    'toolkit_uses_efl%': '<(toolkit_uses_efl)',
+     'toolkit_uses_gtk%': '<(toolkit_uses_gtk)',
+     'use_x11%': '<(use_x11)',
+     'use_gnome_keyring%': '<(use_gnome_keyring)',
+diff --git a/build/linux/system.gyp b/build/linux/system.gyp
+index b925792..4b13e70 100644
+--- a/build/linux/system.gyp
++++ b/build/linux/system.gyp
+@@ -246,6 +246,27 @@
+       ],
+     },
+     {
++      'target_name': 'efl',
++      'type': 'none',
++      'toolsets': ['host', 'target'],
++      'variables': {
++        'efl_libs': 'eina evas ecore ecore-evas ecore-file ecore-imf ecore-input ecore-x edje elementary',
++      },
++      'direct_dependent_settings': {
++        'cflags': [
++          '<!@(<(pkg-config) --cflags <(efl_libs))',
++        ],
++      },
++      'link_settings': {
++        'ldflags': [
++          '<!@(<(pkg-config) --libs-only-L --libs-only-other <(efl_libs))',
++        ],
++        'libraries': [
++          '<!@(<(pkg-config) --libs-only-l <(efl_libs))',
++        ],
++      },
++    },
++    {
+       'target_name': 'freetype2',
+       'type': 'none',
+       'conditions': [
+diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
+index 31f9f17..37cdf9c 100644
+--- a/content/browser/browser_main_loop.cc
++++ b/content/browser/browser_main_loop.cc
+@@ -88,6 +88,10 @@
+ #include "ui/gfx/gtk_util.h"
+ #endif
++#if defined(TOOLKIT_EFL)
++#include "ui/gfx/efl_util.h"
++#endif
++
+ #if defined(OS_POSIX) && !defined(OS_MACOSX)
+ #include <sys/stat.h>
+@@ -289,6 +293,9 @@ BrowserMainLoop::~BrowserMainLoop() {
+ #if !defined(OS_IOS)
+   ui::Clipboard::DestroyClipboardForCurrentThread();
+ #endif  // !defined(OS_IOS)
++#if defined(TOOLKIT_EFL)
++  gfx::EflShutdown();
++#endif
+   g_current_browser_main_loop = NULL;
+ }
+@@ -832,6 +839,10 @@ void BrowserMainLoop::InitializeToolkit() {
+   gfx::GtkInitFromCommandLine(parsed_command_line_);
+ #endif
++#if defined(TOOLKIT_EFL)
++  gfx::EflInit();
++#endif
++
+   SetUpGLibLogHandler();
+ #endif
+diff --git a/content/browser/power_save_blocker_x11.cc b/content/browser/power_save_blocker_x11.cc
+index c7dba77..9a8aff1 100644
+--- a/content/browser/power_save_blocker_x11.cc
++++ b/content/browser/power_save_blocker_x11.cc
+@@ -22,7 +22,9 @@
+ #include "base/memory/scoped_ptr.h"
+ #include "base/memory/singleton.h"
+ #include "base/message_loop_proxy.h"
+-#if defined(TOOLKIT_GTK)
++#if defined(TOOLKIT_EFL)
++#include "base/message_pump_efl.h"
++#elif defined(TOOLKIT_GTK)
+ #include "base/message_pump_gtk.h"
+ #else
+ #include "base/message_pump_aurax11.h"
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+new file mode 100644
+index 0000000..a3a4196
+--- /dev/null
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -0,0 +1,265 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/browser/web_contents/web_contents_view_efl.h"
++
++#include <gdk/gdk.h>
++#include <gdk/gdkkeysyms.h>
++#include <gtk/gtk.h>
++
++#include <algorithm>
++
++#include "base/string_util.h"
++#include "base/utf_string_conversions.h"
++#include "build/build_config.h"
++#include "content/browser/renderer_host/render_view_host_factory.h"
++#include "content/browser/renderer_host/render_view_host_impl.h"
++#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
++#include "content/browser/web_contents/interstitial_page_impl.h"
++#include "content/browser/web_contents/web_contents_impl.h"
++#include "content/browser/web_contents/web_drag_dest_gtk.h"
++#include "content/browser/web_contents/web_drag_source_gtk.h"
++#include "content/public/browser/web_contents_delegate.h"
++#include "content/public/browser/web_contents_view_delegate.h"
++#include "ui/base/gtk/gtk_expanded_container.h"
++#include "ui/gfx/image/image_skia.h"
++#include "ui/gfx/point.h"
++#include "ui/gfx/rect.h"
++#include "ui/gfx/size.h"
++#include "webkit/glue/webdropdata.h"
++
++using WebKit::WebDragOperation;
++using WebKit::WebDragOperationsMask;
++
++namespace content {
++namespace {
++
++// Called when the mouse leaves the widget. We notify our delegate.
++gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
++                       WebContentsImpl* web_contents) {
++  if (web_contents->GetDelegate())
++    web_contents->GetDelegate()->ContentsMouseEvent(
++        web_contents, gfx::Point(event->x_root, event->y_root), false);
++  return FALSE;
++}
++
++// Called when the mouse moves within the widget. We notify our delegate.
++gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
++                     WebContentsImpl* web_contents) {
++  if (web_contents->GetDelegate())
++    web_contents->GetDelegate()->ContentsMouseEvent(
++        web_contents, gfx::Point(event->x_root, event->y_root), true);
++  return FALSE;
++}
++
++// See tab_contents_view_views.cc for discussion of mouse scroll zooming.
++gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
++                       WebContentsImpl* web_contents) {
++  if ((event->state & gtk_accelerator_get_default_mod_mask()) !=
++      GDK_CONTROL_MASK) {
++    return FALSE;
++  }
++
++  WebContentsDelegate* delegate = web_contents->GetDelegate();
++  if (!delegate)
++    return FALSE;
++
++  if (!(event->direction == GDK_SCROLL_DOWN ||
++        event->direction == GDK_SCROLL_UP)) {
++    return FALSE;
++  }
++
++  delegate->ContentsZoomChange(event->direction == GDK_SCROLL_UP);
++  return TRUE;
++}
++
++}  // namespace
++
++WebContentsViewPort* CreateWebContentsView(
++    WebContentsImpl* web_contents,
++    WebContentsViewDelegate* delegate,
++    RenderViewHostDelegateView** render_view_host_delegate_view) {
++  WebContentsViewEfl* rv = new WebContentsViewEfl(web_contents, delegate);
++  *render_view_host_delegate_view = rv;
++  return rv;
++}
++
++WebContentsViewEfl::WebContentsViewEfl(
++    WebContentsImpl* web_contents,
++    WebContentsViewDelegate* delegate)
++    : web_contents_(web_contents),
++      delegate_(delegate) {
++}
++
++WebContentsViewEfl::~WebContentsViewEfl() {
++}
++
++gfx::NativeView WebContentsViewEfl::GetNativeView() const {
++  if (delegate_)
++    return delegate_->GetNativeView();
++
++  return 0;
++}
++
++gfx::NativeView WebContentsViewEfl::GetContentNativeView() const {
++  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
++  if (!rwhv)
++    return NULL;
++  return rwhv->GetNativeView();
++}
++
++gfx::NativeWindow WebContentsViewEfl::GetTopLevelNativeWindow() const {
++  return 0;
++}
++
++void WebContentsViewEfl::GetContainerBounds(gfx::Rect* out) const {
++}
++
++void WebContentsViewEfl::OnTabCrashed(base::TerminationStatus status,
++                                      int error_code) {
++}
++
++void WebContentsViewEfl::Focus() {
++  if (web_contents_->ShowingInterstitialPage()) {
++    web_contents_->GetInterstitialPage()->Focus();
++  } else if (delegate_) {
++    delegate_->Focus();
++  }
++}
++
++void WebContentsViewEfl::SetInitialFocus() {
++  if (web_contents_->FocusLocationBarByDefault())
++    web_contents_->SetFocusToLocationBar(false);
++  else
++    Focus();
++}
++
++void WebContentsViewEfl::StoreFocus() {
++}
++
++void WebContentsViewEfl::RestoreFocus() {
++    SetInitialFocus();
++}
++
++WebDropData* WebContentsViewEfl::GetDropData() const {
++  return 0;
++}
++
++gfx::Rect WebContentsViewEfl::GetViewBounds() const {
++  gfx::Rect rect;
++  GdkWindow* window = gtk_widget_get_window(GetNativeView());
++  if (!window) {
++    rect.SetRect(0, 0, requested_size_.width(), requested_size_.height());
++    return rect;
++  }
++  int x = 0, y = 0, w, h;
++  gdk_window_get_geometry(window, &x, &y, &w, &h, NULL);
++  rect.SetRect(x, y, w, h);
++  return rect;
++}
++
++void WebContentsViewEfl::CreateView(
++    const gfx::Size& initial_size, gfx::NativeView context) {
++  requested_size_ = initial_size;
++}
++
++RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
++    RenderWidgetHost* render_widget_host) {
++  if (render_widget_host->GetView()) {
++    DCHECK(RenderViewHostFactory::has_factory());
++    return render_widget_host->GetView();
++  }
++
++  RenderWidgetHostView* view =
++      RenderWidgetHostView::CreateViewForWidget(render_widget_host);
++  view->InitAsChild(NULL);
++  if (render_widget_host->IsRenderView()) {
++    RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
++    if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
++      UpdateDragDest(rvh);
++  }
++
++  return view;
++}
++
++RenderWidgetHostView* WebContentsViewEfl::CreateViewForPopupWidget(
++    RenderWidgetHost* render_widget_host) {
++  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
++}
++
++void WebContentsViewEfl::SetPageTitle(const string16& title) {
++}
++
++void WebContentsViewEfl::SizeContents(const gfx::Size& size) {
++  requested_size_ = size;
++  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
++  if (rwhv)
++    rwhv->SetSize(size);
++}
++
++void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
++}
++
++void WebContentsViewEfl::RenderViewSwappedIn(RenderViewHost* host) {
++  UpdateDragDest(host);
++}
++
++void WebContentsViewEfl::SetOverscrollControllerEnabled(bool enabled) {
++}
++
++WebContents* WebContentsViewEfl::web_contents() {
++  return web_contents_;
++}
++
++void WebContentsViewEfl::UpdateDragCursor(WebDragOperation operation) {
++}
++
++void WebContentsViewEfl::GotFocus() {
++}
++
++// This is called when the renderer asks us to take focus back (i.e., it has
++// iterated past the last focusable element on the page).
++void WebContentsViewEfl::TakeFocus(bool reverse) {
++  if (!web_contents_->GetDelegate())
++    return;
++  if (!web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
++      GetTopLevelNativeWindow()) {
++    gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()),
++        reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
++  }
++}
++
++void WebContentsViewEfl::UpdateDragDest(RenderViewHost* host) {
++}
++
++void WebContentsViewEfl::ShowContextMenu(
++    const ContextMenuParams& params,
++    ContextMenuSourceType type) {
++  if (delegate_)
++    delegate_->ShowContextMenu(params, type);
++  else
++    DLOG(ERROR) << "Cannot show context menus without a delegate.";
++}
++
++void WebContentsViewEfl::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) {
++  // External popup menus are only used on Mac and Android.
++  NOTIMPLEMENTED();
++}
++
++// Render view DnD -------------------------------------------------------------
++
++void WebContentsViewEfl::StartDragging(const WebDropData& drop_data,
++                                       WebDragOperationsMask ops,
++                                       const gfx::ImageSkia& image,
++                                       const gfx::Vector2d& image_offset,
++                                       const DragEventSourceInfo& event_info) {
++}
++
++}  // namespace content
+diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
+new file mode 100644
+index 0000000..495d4ff
+--- /dev/null
++++ b/content/browser/web_contents/web_contents_view_efl.h
+@@ -0,0 +1,97 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
++#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
++
++#include <vector>
++
++#include "base/memory/scoped_ptr.h"
++#include "content/common/content_export.h"
++#include "content/common/drag_event_source_info.h"
++#include "content/port/browser/render_view_host_delegate_view.h"
++#include "content/port/browser/web_contents_view_port.h"
++
++#include <Evas.h>
++
++namespace content {
++
++class WebContents;
++class WebContentsImpl;
++class WebContentsViewDelegate;
++
++class CONTENT_EXPORT WebContentsViewEfl
++    : public WebContentsViewPort,
++      public RenderViewHostDelegateView {
++ public:
++  WebContentsViewEfl(WebContentsImpl* web_contents,
++                     WebContentsViewDelegate* delegate);
++  virtual ~WebContentsViewEfl();
++
++  WebContentsViewDelegate* delegate() const { return delegate_.get(); }
++  WebContents* web_contents();
++
++  // WebContentsView implementation --------------------------------------------
++
++  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 OnTabCrashed(base::TerminationStatus status,
++                            int error_code) OVERRIDE;
++  virtual void SizeContents(const gfx::Size& size) OVERRIDE;
++  virtual void Focus() OVERRIDE;
++  virtual void SetInitialFocus() OVERRIDE;
++  virtual void StoreFocus() OVERRIDE;
++  virtual void RestoreFocus() OVERRIDE;
++  virtual WebDropData* GetDropData() const OVERRIDE;
++  virtual gfx::Rect GetViewBounds() const OVERRIDE;
++
++  // WebContentsViewPort implementation ----------------------------------------
++  virtual void CreateView(
++      const gfx::Size& initial_size, gfx::NativeView context) OVERRIDE;
++  virtual RenderWidgetHostView* CreateViewForWidget(
++      RenderWidgetHost* render_widget_host) OVERRIDE;
++  virtual RenderWidgetHostView* CreateViewForPopupWidget(
++      RenderWidgetHost* render_widget_host) OVERRIDE;
++  virtual void SetPageTitle(const string16& title) OVERRIDE;
++  virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
++  virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
++  virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
++
++  // Backend implementation of RenderViewHostDelegateView.
++  virtual void ShowContextMenu(
++      const ContextMenuParams& params,
++      ContextMenuSourceType type) 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;
++  virtual void StartDragging(const WebDropData& drop_data,
++                             WebKit::WebDragOperationsMask allowed_ops,
++                             const gfx::ImageSkia& image,
++                             const gfx::Vector2d& image_offset,
++                             const DragEventSourceInfo& event_info) OVERRIDE;
++  virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE;
++  virtual void GotFocus() OVERRIDE;
++  virtual void TakeFocus(bool reverse) OVERRIDE;
++
++ private:
++  void UpdateDragDest(RenderViewHost* new_host);
++
++  WebContentsImpl* web_contents_;
++
++  scoped_ptr<WebContentsViewDelegate> delegate_;
++
++  gfx::Size requested_size_;
++
++  DISALLOW_COPY_AND_ASSIGN(WebContentsViewEfl);
++};
++
++}  // namespace content
++
++#endif  // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
+diff --git a/content/content_browser.gypi b/content/content_browser.gypi
+index 8fcfbc3..d087938 100644
+--- a/content/content_browser.gypi
++++ b/content/content_browser.gypi
+@@ -983,6 +983,8 @@
+     'browser/web_contents/web_contents_view_aura.h',
+     'browser/web_contents/web_contents_view_gtk.cc',
+     'browser/web_contents/web_contents_view_gtk.h',
++    'browser/web_contents/web_contents_view_efl.cc',
++    'browser/web_contents/web_contents_view_efl.h',
+     'browser/web_contents/web_contents_view_guest.cc',
+     'browser/web_contents/web_contents_view_guest.h',
+     'browser/web_contents/web_contents_view_mac.h',
+@@ -1163,6 +1165,15 @@
+         '../dbus/dbus.gyp:dbus',
+       ],
+     }],
++    ['toolkit_uses_efl == 1', {
++      'dependencies': [
++        '../build/linux/system.gyp:efl',
++      ],
++      'sources/': [
++        ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
++        ['exclude', 'browser/web_contents/web_contents_view_gtk.h'],
++      ]
++    }],
+     ['OS=="linux"', {
+       'dependencies': [
+         '../build/linux/system.gyp:udev',
+diff --git a/content/content_shell.gypi b/content/content_shell.gypi
+index 1bf233b..fc8b680 100644
+--- a/content/content_shell.gypi
++++ b/content/content_shell.gypi
+@@ -40,6 +40,7 @@
+         'test_support_content',
+         'content_resources.gyp:content_resources',
+         '../base/base.gyp:base',
++        '<(DEPTH)/build/linux/system.gyp:efl',
+         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+         '../build/temp_gyp/googleurl.gyp:googleurl',
+         '../ipc/ipc.gyp:ipc',
+@@ -82,6 +83,7 @@
+         'shell/shell.h',
+         'shell/shell_android.cc',
+         'shell/shell_aura.cc',
++        'shell/shell_efl.cc',
+         'shell/shell_gtk.cc',
+         'shell/shell_mac.mm',
+         'shell/shell_win.cc',
+@@ -214,6 +216,14 @@
+             ['exclude', 'shell/shell_win.cc'],
+           ],
+         }],  # use_aura==1
++        ['toolkit_uses_efl == 1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++          'sources/': [
++            ['exclude', 'shell/shell_gtk.cc'],
++          ],
++        }],
+         ['chromeos==1', {
+           'dependencies': [
+             '../ash/ash.gyp:ash',
+diff --git a/content/shell/shell.h b/content/shell/shell.h
+index 736bd3f..0d772eb 100644
+--- a/content/shell/shell.h
++++ b/content/shell/shell.h
+@@ -18,7 +18,9 @@
+ #include "ui/gfx/native_widget_types.h"
+ #include "ui/gfx/size.h"
+-#if defined(TOOLKIT_GTK)
++#if defined(TOOLKIT_EFL)
++#include <Evas.h>
++#elif defined(TOOLKIT_GTK)
+ #include <gtk/gtk.h>
+ #include "ui/base/gtk/gtk_signal.h"
+@@ -62,7 +64,7 @@ class Shell : public WebContentsDelegate,
+   void Close();
+   void ShowDevTools();
+   void CloseDevTools();
+-#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK)
++#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL)
+   // Resizes the main window to the given dimensions.
+   void SizeTo(int width, int height);
+ #endif
+@@ -194,6 +196,9 @@ class Shell : public WebContentsDelegate,
+   static ATOM RegisterWindowClass();
+   static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+   static LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);
++#elif defined(TOOLKIT_EFL)
++  static void OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
++                              void* event_info);
+ #elif defined(TOOLKIT_GTK)
+   CHROMEGTK_CALLBACK_0(Shell, void, OnBackButtonClicked);
+   CHROMEGTK_CALLBACK_0(Shell, void, OnForwardButtonClicked);
+@@ -227,6 +232,13 @@ class Shell : public WebContentsDelegate,
+ #if defined(OS_WIN) && !defined(USE_AURA)
+   WNDPROC default_edit_wnd_proc_;
+   static HINSTANCE instance_handle_;
++#elif defined(TOOLKIT_EFL)
++  // TODO(rakuco): Once gfx::NativeWindow is set to Evas_Object*, we
++  // can just use window_.
++  Evas_Object* main_window_;
++
++  int content_width_;
++  int content_height_;
+ #elif defined(TOOLKIT_GTK)
+   GtkWidget* vbox_;
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+new file mode 100644
+index 0000000..19822da
+--- /dev/null
++++ b/content/shell/shell_efl.cc
+@@ -0,0 +1,110 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/shell/shell.h"
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Eina.h>
++#include <Elementary.h>
++
++#include "base/logging.h"
++#include "base/strings/string_piece.h"
++#include "base/utf_string_conversions.h"
++#include "content/public/browser/browser_context.h"
++#include "content/public/browser/native_web_keyboard_event.h"
++#include "content/public/browser/web_contents.h"
++#include "content/public/browser/web_contents_view.h"
++#include "content/public/common/renderer_preferences.h"
++#include "content/shell/shell_browser_context.h"
++#include "content/shell/shell_content_browser_client.h"
++
++namespace content {
++
++void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
++  elm_init(0, NULL);
++  elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
++}
++
++void Shell::PlatformCleanUp() {
++}
++
++void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
++  if (headless_)
++    return;
++}
++
++void Shell::PlatformSetAddressBarURL(const GURL& url) {
++  if (headless_)
++    return;
++}
++
++void Shell::PlatformSetIsLoading(bool loading) {
++  if (headless_)
++    return;
++}
++
++void Shell::PlatformCreateWindow(int width, int height) {
++  SizeTo(width, height);
++
++  if (headless_)
++    return;
++
++  main_window_ = elm_win_add(NULL, "Content Shell", ELM_WIN_BASIC);
++
++  elm_win_title_set(main_window_, "Content Shell");
++  elm_win_autodel_set(main_window_, true);
++
++  evas_object_resize(main_window_, width, height);
++  evas_object_event_callback_add(main_window_, EVAS_CALLBACK_DEL,
++                                 OnMainWindowDel, this);
++
++  Evas_Object* rect = evas_object_rectangle_add(
++      evas_object_evas_get(main_window_));
++  evas_object_color_set(rect, 255, 0, 0, 255);
++  evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  elm_win_resize_object_add(main_window_, rect);
++  evas_object_show(rect);
++
++  evas_object_show(main_window_);
++}
++
++void Shell::PlatformSetContents() {
++  if (headless_)
++    return;
++
++  WebContentsView* content_view = web_contents_->GetView();
++}
++
++void Shell::SizeTo(int width, int height) {
++  content_width_ = width;
++  content_height_ = height;
++}
++
++void Shell::PlatformResizeSubViews() {
++  SizeTo(content_width_, content_height_);
++}
++
++void Shell::Close() {
++  if (headless_) {
++    delete this;
++    return;
++  }
++}
++
++void Shell::PlatformSetTitle(const string16& title) {
++  if (headless_)
++    return;
++
++  std::string title_utf8 = UTF16ToUTF8(title);
++  elm_win_title_set(main_window_, title_utf8.c_str());
++}
++
++void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
++                            void* event_info) {
++  Shell* shell = static_cast<Shell*>(data);
++  delete shell;
++}
++
++}  // namespace content
+diff --git a/ui/gfx/efl_util.cc b/ui/gfx/efl_util.cc
+new file mode 100644
+index 0000000..7cd7cb4
+--- /dev/null
++++ b/ui/gfx/efl_util.cc
+@@ -0,0 +1,33 @@
++// Copyright (c) 2013 Intel Coporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/gfx/efl_util.h"
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Ecore_X.h>
++#include <Edje.h>
++#include <Eina.h>
++#include <Evas.h>
++
++namespace gfx {
++
++void EflInit() {
++  eina_init();
++  evas_init();
++  ecore_init();
++  ecore_evas_init();
++  edje_init();
++  ecore_main_loop_glib_integrate();
++}
++
++void EflShutdown() {
++  edje_shutdown();
++  ecore_evas_shutdown();
++  ecore_shutdown();
++  evas_shutdown();
++  eina_shutdown();
++}
++
++}  // namespace gfx
+diff --git a/ui/gfx/efl_util.h b/ui/gfx/efl_util.h
+new file mode 100644
+index 0000000..8f11bed
+--- /dev/null
++++ b/ui/gfx/efl_util.h
+@@ -0,0 +1,20 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef UI_GFX_EFL_UTIL_H_
++#define UI_GFX_EFL_UTIL_H_
++
++#include <vector>
++
++#include "base/time.h"
++#include "ui/base/ui_export.h"
++
++namespace gfx {
++
++UI_EXPORT void EflInit();
++UI_EXPORT void EflShutdown();
++
++}  // namespace gfx
++
++#endif  // UI_GFX_EFL_UTIL_H_
+diff --git a/ui/ui.gyp b/ui/ui.gyp
+index 9169e08..797fd78 100644
+--- a/ui/ui.gyp
++++ b/ui/ui.gyp
+@@ -693,6 +693,15 @@
+             'gfx/image/cairo_cached_surface.h',
+           ],
+         }],
++        ['toolkit_uses_efl == 1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++          'sources': [
++            'gfx/efl_util.cc',
++            'gfx/efl_util.h',
++          ],
++        }],
+         ['chromeos==1 or (use_aura==1 and OS=="linux" and use_x11==0)', {
+           'sources!': [
+             'base/clipboard/clipboard_aurax11.cc',
+-- 
+1.8.1.2
+
diff --git a/patchset/0002-Adding-RenderWidgetHostViewEfl.patch b/patchset/0002-Adding-RenderWidgetHostViewEfl.patch
new file mode 100644 (file)
index 0000000..876ccdd
--- /dev/null
@@ -0,0 +1,2158 @@
+From fe1a73dd1f8f1fb57132e431db2c4fc3e603e6c6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <dominik.rottsches@intel.com>
+Date: Fri, 14 Jun 2013 17:47:58 +0300
+Subject: [PATCH 02/33] Adding RenderWidgetHostViewEfl
+
+Pass parent container to WebContentsViewEfl
+Added Screen_efl.cc
+Introduce view container
+---
+ content/browser/gpu/compositor_util.cc             |   2 +-
+ .../renderer_host/render_widget_host_view_efl.cc   | 777 +++++++++++++++++++++
+ .../renderer_host/render_widget_host_view_efl.h    | 317 +++++++++
+ content/browser/renderer_host/window_utils_efl.cc  |  51 ++
+ content/browser/renderer_host/window_utils_efl.h   |  20 +
+ .../browser/web_contents/web_contents_view_efl.cc  |  10 +-
+ .../browser/web_contents/web_contents_view_efl.h   |   6 +
+ content/content_browser.gypi                       |   8 +
+ content/content_shell.gypi                         |   2 +
+ content/shell/shell_efl.cc                         |  20 +-
+ content/shell/shell_web_contents_view_delegate.h   |   2 +-
+ .../shell/shell_web_contents_view_delegate_efl.cc  |  71 ++
+ ui/gfx/efl_util.cc                                 |   2 +
+ ui/gfx/preserve_window_delegate_efl.h              |  47 ++
+ ui/gfx/preserve_window_efl.cc                      | 421 +++++++++++
+ ui/gfx/preserve_window_efl.h                       |  37 +
+ ui/gfx/screen_efl.cc                               |  87 +++
+ ui/ui.gyp                                          |   9 +
+ 18 files changed, 1869 insertions(+), 20 deletions(-)
+ create mode 100644 content/browser/renderer_host/render_widget_host_view_efl.cc
+ create mode 100644 content/browser/renderer_host/render_widget_host_view_efl.h
+ create mode 100644 content/browser/renderer_host/window_utils_efl.cc
+ create mode 100644 content/browser/renderer_host/window_utils_efl.h
+ create mode 100644 content/shell/shell_web_contents_view_delegate_efl.cc
+ create mode 100644 ui/gfx/preserve_window_delegate_efl.h
+ create mode 100644 ui/gfx/preserve_window_efl.cc
+ create mode 100644 ui/gfx/preserve_window_efl.h
+ create mode 100644 ui/gfx/screen_efl.cc
+
+diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
+index 0b34932..2cdcd7a 100644
+--- a/content/browser/gpu/compositor_util.cc
++++ b/content/browser/gpu/compositor_util.cc
+@@ -77,7 +77,7 @@ bool IsThreadedCompositingEnabled() {
+ }
+ bool IsForceCompositingModeEnabled() {
+-#if defined(OS_WIN) && defined(USE_AURA)
++#if defined(OS_WIN) && defined(USE_AURA) || defined(TOOLKIT_EFL)
+   // We always want compositing on Aura Windows.
+   return true;
+ #endif
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+new file mode 100644
+index 0000000..86fe664
+--- /dev/null
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -0,0 +1,777 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/browser/renderer_host/render_widget_host_view_efl.h"
++
++#include <Elementary.h>
++
++// If this gets included after the gtk headers, then a bunch of compiler
++// errors happen because of a "#define Status int" in Xlib.h, which interacts
++// badly with net::URLRequestStatus::Status.
++#include "content/common/view_messages.h"
++
++#include <cairo/cairo.h>
++
++#include <algorithm>
++#include <string>
++
++#include "base/bind_helpers.h"
++#include "base/command_line.h"
++#include "base/debug/trace_event.h"
++#include "base/logging.h"
++#include "base/message_loop.h"
++#include "base/metrics/histogram.h"
++#include "base/string_number_conversions.h"
++#include "base/strings/utf_offset_string_conversions.h"
++#include "base/time.h"
++#include "base/utf_string_conversions.h"
++#include "content/browser/accessibility/browser_accessibility_gtk.h"
++#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
++#include "content/browser/renderer_host/backing_store_gtk.h"
++#include "content/browser/renderer_host/render_view_host_delegate.h"
++#include "content/browser/renderer_host/render_view_host_impl.h"
++#include "content/browser/renderer_host/window_utils_efl.h"
++#include "content/common/edit_command.h"
++#include "content/common/gpu/gpu_messages.h"
++#include "content/public/browser/browser_context.h"
++#include "content/public/browser/native_web_keyboard_event.h"
++#include "content/public/common/content_switches.h"
++#include "skia/ext/platform_canvas.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
++#include "ui/base/clipboard/scoped_clipboard_writer.h"
++#include "ui/base/gtk/gtk_compat.h"
++#include "ui/base/text/text_elider.h"
++#include "ui/base/x/active_window_watcher_x.h"
++#include "ui/base/x/x11_util.h"
++#include "ui/gfx/preserve_window_efl.h"
++#include "webkit/glue/webcursor_gtk_data.h"
++#include "webkit/plugins/npapi/webplugin.h"
++
++using WebKit::WebInputEventFactory;
++using WebKit::WebMouseWheelEvent;
++using WebKit::WebScreenInfo;
++
++namespace content {
++namespace {
++
++// Paint rects on Linux are bounded by the maximum size of a shared memory
++// region. By default that's 32MB, but many distros increase it significantly
++// (i.e. to 256MB).
++//
++// We fetch the maximum value from /proc/sys/kernel/shmmax at runtime and, if
++// we exceed that, then we limit the height of the paint rect in the renderer.
++//
++// These constants are here to ensure that, in the event that we exceed it, we
++// end up with something a little more square. Previously we had 4000x4000, but
++// people's monitor setups are actually exceeding that these days.
++const int kMaxWindowWidth = 10000;
++const int kMaxWindowHeight = 10000;
++
++// See WebInputEventFactor.cpp for a reason for this being the default
++// scroll size for linux.
++const float kDefaultScrollPixelsPerTick = 160.0f / 3.0f;
++
++const GdkColor kBGColor =
++#if defined(NDEBUG)
++  { 0, 0xff * 257, 0xff * 257, 0xff * 257 };
++#else
++  { 0, 0x00 * 257, 0xff * 257, 0x00 * 257 };
++#endif
++
++// Returns the spinning cursor used for loading state.
++GdkCursor* GetMozSpinningCursor() {
++  static GdkCursor* moz_spinning_cursor = NULL;
++  if (!moz_spinning_cursor) {
++    const GdkColor fg = { 0, 0, 0, 0 };
++    const GdkColor bg = { 65535, 65535, 65535, 65535 };
++    GdkPixmap* source = gdk_bitmap_create_from_data(
++        NULL, reinterpret_cast<const gchar*>(moz_spinning_bits), 32, 32);
++    GdkPixmap* mask = gdk_bitmap_create_from_data(
++        NULL, reinterpret_cast<const gchar*>(moz_spinning_mask_bits), 32, 32);
++    moz_spinning_cursor =
++        gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
++    g_object_unref(source);
++    g_object_unref(mask);
++  }
++  return moz_spinning_cursor;
++}
++
++bool MovedToPoint(const WebKit::WebMouseEvent& mouse_event,
++                   const gfx::Point& center) {
++  return mouse_event.globalX == center.x() &&
++         mouse_event.globalY == center.y();
++}
++
++}  // namespace
++
++RenderWidgetHostViewEfl::RenderWidgetHostViewEfl(RenderWidgetHost* widget_host)
++    : host_(RenderWidgetHostImpl::From(widget_host)),
++      about_to_validate_and_paint_(false),
++      is_hidden_(false),
++      is_loading_(false),
++      parent_(NULL),
++      is_popup_first_mouse_release_(true),
++      was_imcontext_focused_before_grab_(false),
++      do_x_grab_(false),
++      is_fullscreen_(false),
++      made_active_(false),
++      mouse_is_being_warped_to_unlocked_position_(false),
++      destroy_handler_id_(0),
++      dragged_at_horizontal_edge_(0),
++      dragged_at_vertical_edge_(0),
++      compositing_surface_(gfx::kNullPluginWindow),
++      preserve_window_(0) {
++  host_->SetView(this);
++}
++
++RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
++  UnlockMouse();
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) {
++  return false;
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) {
++  return false;
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) {
++return false;
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) {
++  return false;
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowKeyDown(Evas_Event_Key_Down* event) {
++  return false;
++}
++
++bool RenderWidgetHostViewEfl::PreserveWindowKeyUp(Evas_Event_Key_Up* event) {
++  return false;
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowFocusIn() {
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowFocusOut() {
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowShow() {
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowHide() {
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowMove(const gfx::Point& origin) {
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowResize(const gfx::Size& size) {
++  SetSize(size);
++}
++
++void RenderWidgetHostViewEfl::PreserveWindowRepaint(const gfx::Rect& damage_rect) {
++  Paint(damage_rect);
++}
++
++bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
++  bool handled = true;
++  IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewEfl, message)
++    IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer,
++                        OnCreatePluginContainer)
++    IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
++                        OnDestroyPluginContainer)
++    IPC_MESSAGE_UNHANDLED(handled = false)
++  IPC_END_MESSAGE_MAP()
++  return handled;
++}
++
++void RenderWidgetHostViewEfl::InitAsChild(
++    gfx::NativeView parent_view) {
++  Evas_Object* elm_box = reinterpret_cast<Evas_Object*>(parent_view);
++  Evas* evas = evas_object_evas_get(elm_box);
++  preserve_window_ = gfx::PreserveWindow::Create(this, evas);
++  evas_object_size_hint_align_set(preserve_window_->SmartObject(), EVAS_HINT_FILL, EVAS_HINT_FILL);
++  evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  elm_box_pack_end(elm_box, preserve_window_->SmartObject());
++  evas_object_show(preserve_window_->SmartObject());
++  compositing_surface_ = elm_win_xwindow_get(preserve_window_->EvasWindow());
++}
++
++void RenderWidgetHostViewEfl::InitAsPopup(
++    RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
++  // If we aren't a popup, then |window| will be leaked.
++  DCHECK(IsPopup());
++}
++
++void RenderWidgetHostViewEfl::InitAsFullscreen(
++    RenderWidgetHostView* reference_host_view) {
++  DCHECK(reference_host_view);
++}
++
++RenderWidgetHost* RenderWidgetHostViewEfl::GetRenderWidgetHost() const {
++  return host_;
++}
++
++void RenderWidgetHostViewEfl::WasShown() {
++  if (!is_hidden_)
++    return;
++
++  if (web_contents_switch_paint_time_.is_null())
++    web_contents_switch_paint_time_ = base::TimeTicks::Now();
++  is_hidden_ = false;
++  host_->WasShown();
++}
++
++void RenderWidgetHostViewEfl::WasHidden() {
++  if (is_hidden_)
++    return;
++
++  // If we receive any more paint messages while we are hidden, we want to
++  // ignore them so we don't re-allocate the backing store.  We will paint
++  // everything again when we become selected again.
++  is_hidden_ = true;
++
++  // If we have a renderer, then inform it that we are being hidden so it can
++  // reduce its resource utilization.
++  host_->WasHidden();
++
++  web_contents_switch_paint_time_ = base::TimeTicks();
++}
++
++void RenderWidgetHostViewEfl::SetSize(const gfx::Size& size) {
++  int width = std::min(size.width(), kMaxWindowWidth);
++  int height = std::min(size.height(), kMaxWindowHeight);
++  if (IsPopup()) {
++    // We're a popup, honor the size request.
++  }
++
++  // Update the size of the RWH.
++  if (requested_size_.width() != width ||
++      requested_size_.height() != height) {
++    requested_size_ = gfx::Size(width, height);
++    host_->SendScreenRects();
++    host_->WasResized();
++  }
++}
++
++void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
++  SetSize(rect.size());
++}
++
++gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
++  return reinterpret_cast<gfx::NativeView>(preserve_window_->SmartObject());
++}
++
++gfx::NativeViewId RenderWidgetHostViewEfl::GetNativeViewId() const {
++  return 0;
++}
++
++gfx::NativeViewAccessible RenderWidgetHostViewEfl::GetNativeViewAccessible() {
++  NOTIMPLEMENTED();
++  return NULL;
++}
++
++void RenderWidgetHostViewEfl::MovePluginWindows(
++    const gfx::Vector2d& scroll_offset,
++    const std::vector<webkit::npapi::WebPluginGeometry>& moves) {
++}
++
++void RenderWidgetHostViewEfl::Focus() {
++}
++
++void RenderWidgetHostViewEfl::Blur() {
++  // TODO(estade): We should be clearing native focus as well, but I know of no
++  // way to do that without focusing another widget.
++  host_->Blur();
++}
++
++bool RenderWidgetHostViewEfl::HasFocus() const {
++  return true;
++}
++
++void RenderWidgetHostViewEfl::ActiveWindowChanged(GdkWindow* window) {
++}
++
++bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
++  return host_->Send(message);
++}
++
++bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
++  return true;
++}
++
++void RenderWidgetHostViewEfl::Show() {
++}
++
++void RenderWidgetHostViewEfl::Hide() {
++}
++
++bool RenderWidgetHostViewEfl::IsShowing() {
++  return true;
++}
++
++gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
++  return gfx::Rect(requested_size_);
++}
++
++void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& cursor) {
++  // Optimize the common case, where the cursor hasn't changed.
++  // However, we can switch between different pixmaps, so only on the
++  // non-pixmap branch.
++  if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
++      current_cursor_.GetCursorType() == cursor.GetCursorType()) {
++    return;
++  }
++
++  current_cursor_ = cursor;
++  ShowCurrentCursor();
++}
++
++void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
++  is_loading_ = is_loading;
++  // Only call ShowCurrentCursor() when it will actually change the cursor.
++  if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
++    ShowCurrentCursor();
++}
++
++void RenderWidgetHostViewEfl::TextInputStateChanged(
++    const ViewHostMsg_TextInputState_Params& params) {
++}
++
++void RenderWidgetHostViewEfl::ImeCancelComposition() {
++}
++
++void RenderWidgetHostViewEfl::ImeCompositionRangeChanged(
++    const ui::Range& range,
++    const std::vector<gfx::Rect>& character_bounds) {
++}
++
++void RenderWidgetHostViewEfl::DidUpdateBackingStore(
++    const gfx::Rect& scroll_rect,
++    const gfx::Vector2d& scroll_delta,
++    const std::vector<gfx::Rect>& copy_rects) {
++  TRACE_EVENT0("ui::efl", "RenderWidgetHostViewEfl::DidUpdateBackingStore");
++
++  if (is_hidden_)
++    return;
++
++  // TODO(darin): Implement the equivalent of Win32's ScrollWindowEX.  Can that
++  // be done using XCopyArea?  Perhaps similar to
++  // BackingStore::ScrollBackingStore?
++  if (about_to_validate_and_paint_)
++    invalid_rect_.Union(scroll_rect);
++  else
++    Paint(scroll_rect);
++
++  for (size_t i = 0; i < copy_rects.size(); ++i) {
++    // Avoid double painting.  NOTE: This is only relevant given the call to
++    // Paint(scroll_rect) above.
++    gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
++    if (rect.IsEmpty())
++      continue;
++
++    if (about_to_validate_and_paint_)
++      invalid_rect_.Union(rect);
++    else
++      Paint(rect);
++  }
++}
++
++void RenderWidgetHostViewEfl::RenderViewGone(base::TerminationStatus status,
++                                             int error_code) {
++  Destroy();
++}
++
++void RenderWidgetHostViewEfl::Destroy() {
++  if (compositing_surface_ != gfx::kNullPluginWindow) {
++  }
++  if (do_x_grab_) {
++    // Undo the X grab.
++  }
++
++  if (preserve_window_->SmartObject()) {
++    // If this is a popup or fullscreen widget, then we need to destroy the
++    // window that we created to hold it.
++    if (IsPopup() || is_fullscreen_) {
++      ui::ActiveWindowWatcherX::RemoveObserver(this);
++    }
++    // See http://crbug.com/11847 for details.
++  }
++  // The RenderWidgetHost's destruction led here, so don't call it.
++  host_ = NULL;
++
++  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
++}
++
++void RenderWidgetHostViewEfl::SetTooltipText(const string16& tooltip_text) {
++  // I filed https://bugzilla.gnome.org/show_bug.cgi?id=604641 upstream.
++}
++
++void RenderWidgetHostViewEfl::SelectionChanged(const string16& text,
++                                               size_t offset,
++                                               const ui::Range& range) {
++  RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
++
++  if (text.empty() || range.is_empty())
++    return;
++  size_t pos = range.GetMin() - offset;
++  size_t n = range.length();
++
++  DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
++  if (pos >= text.length()) {
++    NOTREACHED() << "The text can not cover range.";
++    return;
++  }
++
++  BrowserContext* browser_context = host_->GetProcess()->GetBrowserContext();
++  // Set the BUFFER_SELECTION to the ui::Clipboard.
++  ui::ScopedClipboardWriter clipboard_writer(
++      ui::Clipboard::GetForCurrentThread(),
++      ui::Clipboard::BUFFER_SELECTION,
++      BrowserContext::GetMarkerForOffTheRecordContext(browser_context));
++  clipboard_writer.WriteText(text.substr(pos, n));
++}
++
++void RenderWidgetHostViewEfl::SelectionBoundsChanged(
++    const ViewHostMsg_SelectionBounds_Params& params) {
++}
++
++void RenderWidgetHostViewEfl::ScrollOffsetChanged() {
++}
++
++GdkEventButton* RenderWidgetHostViewEfl::GetLastMouseDown() {
++  return 0;
++}
++
++gfx::NativeView RenderWidgetHostViewEfl::BuildInputMethodsGtkMenu() {
++  return 0;
++}
++
++bool RenderWidgetHostViewEfl::NeedsInputGrab() {
++  return popup_type_ == WebKit::WebPopupTypeSelect;
++}
++
++bool RenderWidgetHostViewEfl::IsPopup() const {
++  return popup_type_ != WebKit::WebPopupTypeNone;
++}
++
++void RenderWidgetHostViewEfl::DoSharedInit(Evas_Object* parent) {
++}
++
++void RenderWidgetHostViewEfl::DoPopupOrFullscreenInit(GtkWindow* window,
++                                                      const gfx::Rect& bounds) {
++}
++
++BackingStore* RenderWidgetHostViewEfl::AllocBackingStore(
++    const gfx::Size& /*size*/) {
++  return 0;  // We're using accelerated path.
++}
++
++void RenderWidgetHostViewEfl::CopyFromCompositingSurface(
++    const gfx::Rect& src_subrect,
++    const gfx::Size& /* dst_size */,
++    const base::Callback<void(bool, const SkBitmap&)>& callback) {
++  // Grab the snapshot from the renderer as that's the only reliable way to
++  // readback from the GPU for this platform right now.
++  GetRenderWidgetHost()->GetSnapshotFromRenderer(src_subrect, callback);
++}
++
++void RenderWidgetHostViewEfl::CopyFromCompositingSurfaceToVideoFrame(
++      const gfx::Rect& src_subrect,
++      const scoped_refptr<media::VideoFrame>& target,
++      const base::Callback<void(bool)>& callback) {
++  NOTIMPLEMENTED();
++  callback.Run(false);
++}
++
++bool RenderWidgetHostViewEfl::CanCopyToVideoFrame() const {
++  return false;
++}
++
++void RenderWidgetHostViewEfl::AcceleratedSurfaceBuffersSwapped(
++    const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
++    int gpu_host_id) {
++    AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
++    ack_params.sync_point = 0;
++    RenderWidgetHostImpl::AcknowledgeBufferPresent(
++      params.route_id, gpu_host_id, ack_params);
++}
++
++void RenderWidgetHostViewEfl::AcceleratedSurfacePostSubBuffer(
++    const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
++    int gpu_host_id) {
++    AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
++    ack_params.sync_point = 0;
++    RenderWidgetHostImpl::AcknowledgeBufferPresent(
++      params.route_id, gpu_host_id, ack_params);
++}
++
++void RenderWidgetHostViewEfl::AcceleratedSurfaceSuspend() {
++}
++
++void RenderWidgetHostViewEfl::AcceleratedSurfaceRelease() {
++}
++
++bool RenderWidgetHostViewEfl::HasAcceleratedSurface(
++      const gfx::Size& desired_size) {
++  // TODO(jbates) Implement this so this view can use GetBackingStore for both
++  // software and GPU frames. Defaulting to false just makes GetBackingStore
++  // only useable for software frames.
++  return false;
++}
++
++void RenderWidgetHostViewEfl::SetBackground(const SkBitmap& background) {
++  RenderWidgetHostViewBase::SetBackground(background);
++  Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
++}
++
++void RenderWidgetHostViewEfl::ModifyEventForEdgeDragging(
++    GtkWidget* widget, GdkEventMotion* event) {
++  // If the widget is aligned with an edge of the monitor its on and the user
++  // attempts to drag past that edge we track the number of times it has
++  // occurred, so that we can force the widget to scroll when it otherwise
++  // would be unable to, by modifying the (x,y) position in the drag
++  // event that we forward on to webkit. If we get a move that's no longer a
++  // drag or a drag indicating the user is no longer at that edge we stop
++  // altering the drag events.
++  int new_dragged_at_horizontal_edge = 0;
++  int new_dragged_at_vertical_edge = 0;
++  // Used for checking the edges of the monitor. We cache the values to save
++  // roundtrips to the X server.
++  CR_DEFINE_STATIC_LOCAL(gfx::Size, drag_monitor_size, ());
++  if (event->state & GDK_BUTTON1_MASK) {
++    if (drag_monitor_size.IsEmpty()) {
++      // We can safely cache the monitor size for the duration of a drag.
++      GdkScreen* screen = gtk_widget_get_screen(widget);
++      int monitor =
++          gdk_screen_get_monitor_at_point(screen, event->x_root, event->y_root);
++      GdkRectangle geometry;
++      gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
++      drag_monitor_size.SetSize(geometry.width, geometry.height);
++    }
++    GtkAllocation allocation;
++    gtk_widget_get_allocation(widget, &allocation);
++    // Check X and Y independently, as the user could be dragging into a corner.
++    if (event->x == 0 && event->x_root == 0) {
++      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ - 1;
++    } else if (allocation.width - 1 == static_cast<gint>(event->x) &&
++        drag_monitor_size.width() - 1 == static_cast<gint>(event->x_root)) {
++      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ + 1;
++    }
++
++    if (event->y == 0 && event->y_root == 0) {
++      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ - 1;
++    } else if (allocation.height - 1 == static_cast<gint>(event->y) &&
++        drag_monitor_size.height() - 1 == static_cast<gint>(event->y_root)) {
++      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ + 1;
++    }
++
++    event->x_root += new_dragged_at_horizontal_edge;
++    event->x += new_dragged_at_horizontal_edge;
++    event->y_root += new_dragged_at_vertical_edge;
++    event->y += new_dragged_at_vertical_edge;
++  } else {
++    // Clear whenever we get a non-drag mouse move.
++    drag_monitor_size.SetSize(0, 0);
++  }
++  dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge;
++  dragged_at_vertical_edge_ = new_dragged_at_vertical_edge;
++}
++
++void RenderWidgetHostViewEfl::Paint(const gfx::Rect& /*damage_rect*/) {
++  // If the GPU process is rendering directly into the View,
++  // call the compositor directly.
++  host_->ScheduleComposite();
++}
++
++void RenderWidgetHostViewEfl::ShowCurrentCursor() {
++}
++
++void RenderWidgetHostViewEfl::SetHasHorizontalScrollbar(
++    bool has_horizontal_scrollbar) {
++}
++
++void RenderWidgetHostViewEfl::SetScrollOffsetPinning(
++    bool is_pinned_to_left, bool is_pinned_to_right) {
++}
++
++void RenderWidgetHostViewEfl::OnAcceleratedCompositingStateChange() {
++}
++
++void RenderWidgetHostViewEfl::GetScreenInfo(WebScreenInfo* results) {
++  content::GetScreenInfoEfl(results);
++}
++
++gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
++  return GetViewBounds();
++}
++
++gfx::GLSurfaceHandle RenderWidgetHostViewEfl::GetCompositingSurface() {
++  return gfx::GLSurfaceHandle(compositing_surface_, gfx::NATIVE_TRANSPORT);
++}
++
++bool RenderWidgetHostViewEfl::LockMouse() {
++  return false;
++}
++
++void RenderWidgetHostViewEfl::UnlockMouse() {
++}
++
++void RenderWidgetHostViewEfl::ForwardKeyboardEvent(
++    const NativeWebKeyboardEvent& event) {
++}
++
++bool RenderWidgetHostViewEfl::RetrieveSurrounding(std::string* text,
++                                                  size_t* cursor_index) {
++  if (!selection_range_.IsValid())
++    return false;
++
++  size_t offset = selection_range_.GetMin() - selection_text_offset_;
++  DCHECK(offset <= selection_text_.length());
++
++  if (offset == selection_text_.length()) {
++    *text = UTF16ToUTF8(selection_text_);
++    *cursor_index = text->length();
++    return true;
++  }
++
++  *text = base::UTF16ToUTF8AndAdjustOffset(
++      base::StringPiece16(selection_text_), &offset);
++  if (offset == string16::npos) {
++    NOTREACHED() << "Invalid offset in UTF16 string.";
++    return false;
++  }
++  *cursor_index = offset;
++  return true;
++}
++
++void RenderWidgetHostViewEfl::MarkCachedWidgetCenterStale() {
++  widget_center_valid_ = false;
++  mouse_has_been_warped_to_new_center_ = false;
++}
++
++gfx::Point RenderWidgetHostViewEfl::GetWidgetCenter() {
++  return gfx::Point();
++}
++
++void RenderWidgetHostViewEfl::ModifyEventMovementAndCoords(
++    WebKit::WebMouseEvent* event) {
++  // Movement is computed by taking the difference of the new cursor position
++  // and the previous. Under mouse lock the cursor will be warped back to the
++  // center so that we are not limited by clipping boundaries.
++  // We do not measure movement as the delta from cursor to center because
++  // we may receive more mouse movement events before our warp has taken
++  // effect.
++  event->movementX = event->globalX - global_mouse_position_.x();
++  event->movementY = event->globalY - global_mouse_position_.y();
++
++  // While the cursor is being warped back to the unlocked position, suppress
++  // the movement member data.
++  if (mouse_is_being_warped_to_unlocked_position_) {
++    event->movementX = 0;
++    event->movementY = 0;
++    if (MovedToPoint(*event, unlocked_global_mouse_position_))
++      mouse_is_being_warped_to_unlocked_position_ = false;
++  }
++
++  global_mouse_position_.SetPoint(event->globalX, event->globalY);
++
++  // Under mouse lock, coordinates of mouse are locked to what they were when
++  // mouse lock was entered.
++  if (mouse_locked_) {
++    event->x = unlocked_mouse_position_.x();
++    event->y = unlocked_mouse_position_.y();
++    event->windowX = unlocked_mouse_position_.x();
++    event->windowY = unlocked_mouse_position_.y();
++    event->globalX = unlocked_global_mouse_position_.x();
++    event->globalY = unlocked_global_mouse_position_.y();
++  } else {
++    unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
++    unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
++  }
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// RenderWidgetHostView, public:
++
++// static
++RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
++    RenderWidgetHost* widget) {
++  return new RenderWidgetHostViewEfl(widget);
++}
++
++// static
++void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
++}
++
++void RenderWidgetHostViewEfl::SetAccessibilityFocus(int acc_obj_id) {
++  if (!host_)
++    return;
++  host_->AccessibilitySetFocus(acc_obj_id);
++}
++
++void RenderWidgetHostViewEfl::AccessibilityDoDefaultAction(int acc_obj_id) {
++  if (!host_)
++    return;
++  host_->AccessibilityDoDefaultAction(acc_obj_id);
++}
++
++void RenderWidgetHostViewEfl::AccessibilityScrollToMakeVisible(
++    int acc_obj_id, gfx::Rect subfocus) {
++  if (!host_)
++    return;
++
++  host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
++}
++
++void RenderWidgetHostViewEfl::AccessibilityScrollToPoint(
++    int acc_obj_id, gfx::Point point) {
++  if (!host_)
++    return;
++  host_->AccessibilityScrollToPoint(acc_obj_id, point);
++}
++
++void RenderWidgetHostViewEfl::AccessibilitySetTextSelection(
++    int acc_obj_id, int start_offset, int end_offset) {
++  if (!host_)
++    return;
++
++  host_->AccessibilitySetTextSelection(acc_obj_id, start_offset, end_offset);
++}
++
++gfx::Point RenderWidgetHostViewEfl::GetLastTouchEventLocation() const {
++  return gfx::Point();
++}
++
++void RenderWidgetHostViewEfl::FatalAccessibilityTreeError() {
++  if (host_) {
++    host_->FatalAccessibilityTreeError();
++    SetBrowserAccessibilityManager(NULL);
++  } else {
++    CHECK(FALSE);
++  }
++}
++
++void RenderWidgetHostViewEfl::OnAccessibilityNotifications(
++    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
++}
++
++AtkObject* RenderWidgetHostViewEfl::GetAccessible() {
++  return 0;
++}
++
++void RenderWidgetHostViewEfl::OnCreatePluginContainer(
++    gfx::PluginWindowHandle id) {
++}
++
++void RenderWidgetHostViewEfl::OnDestroyPluginContainer(
++    gfx::PluginWindowHandle id) {
++}
++
++}  // namespace content
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.h b/content/browser/renderer_host/render_widget_host_view_efl.h
+new file mode 100644
+index 0000000..2aba48f
+--- /dev/null
++++ b/content/browser/renderer_host/render_widget_host_view_efl.h
+@@ -0,0 +1,317 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
++#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
++
++#include <Evas.h>
++#include <gdk/gdk.h>
++
++#include <string>
++#include <vector>
++
++#include "base/memory/scoped_ptr.h"
++#include "base/time.h"
++#include "content/browser/accessibility/browser_accessibility_manager.h"
++#include "content/browser/renderer_host/render_widget_host_view_base.h"
++#include "content/common/content_export.h"
++#include "ipc/ipc_sender.h"
++#include "ui/base/animation/animation_delegate.h"
++#include "ui/base/animation/slide_animation.h"
++#include "ui/base/x/active_window_watcher_x_observer.h"
++#include "ui/gfx/native_widget_types.h"
++#include "ui/gfx/point.h"
++#include "ui/gfx/preserve_window_delegate_efl.h"
++#include "ui/gfx/rect.h"
++#include "webkit/glue/webcursor.h"
++#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
++
++typedef struct _GtkClipboard GtkClipboard;
++typedef struct _GtkSelectionData GtkSelectionData;
++
++namespace gfx {
++class PreserveWindow;
++}
++
++namespace content {
++class RenderWidgetHost;
++class RenderWidgetHostImpl;
++struct NativeWebKeyboardEvent;
++
++// -----------------------------------------------------------------------------
++// See comments in render_widget_host_view.h about this class and its members.
++// -----------------------------------------------------------------------------
++class CONTENT_EXPORT RenderWidgetHostViewEfl
++    : public gfx::PreserveWindowDelegate,
++      public RenderWidgetHostViewBase,
++      public BrowserAccessibilityDelegate,
++      public ui::ActiveWindowWatcherXObserver,
++      public IPC::Sender {
++ public:
++  virtual ~RenderWidgetHostViewEfl();
++
++  // PreserveWindowDelegate implementation.
++  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event);
++  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event);
++  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event);
++  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event);
++  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event);
++  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event);
++  virtual void PreserveWindowFocusIn();
++  virtual void PreserveWindowFocusOut();
++  virtual void PreserveWindowShow();
++  virtual void PreserveWindowHide();
++  virtual void PreserveWindowMove(const gfx::Point& origin);
++  virtual void PreserveWindowResize(const gfx::Size& size);
++  virtual void PreserveWindowRepaint(const gfx::Rect& damage_rect);
++
++
++  // RenderWidgetHostView implementation.
++  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
++  virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
++  virtual 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;
++  virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
++  virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
++  virtual void SetBackground(const SkBitmap& background) OVERRIDE;
++
++  // RenderWidgetHostViewPort implementation.
++  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 ImeCompositionRangeChanged(
++      const ui::Range& range,
++      const std::vector<gfx::Rect>& character_bounds) 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;
++  virtual void Destroy() OVERRIDE;
++  virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
++  virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
++  virtual void SelectionChanged(const string16& text,
++                                size_t offset,
++                                const ui::Range& range) OVERRIDE;
++  virtual void SelectionBoundsChanged(
++      const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
++  virtual void ScrollOffsetChanged() OVERRIDE;
++  virtual 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, const SkBitmap&)>& callback) OVERRIDE;
++  virtual void CopyFromCompositingSurfaceToVideoFrame(
++      const gfx::Rect& src_subrect,
++      const scoped_refptr<media::VideoFrame>& target,
++      const base::Callback<void(bool)>& callback) OVERRIDE;
++  virtual bool CanCopyToVideoFrame() const OVERRIDE;
++  virtual void OnAcceleratedCompositingStateChange() 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 void AcceleratedSurfaceRelease() OVERRIDE;
++  virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
++  virtual void SetHasHorizontalScrollbar(
++      bool has_horizontal_scrollbar) OVERRIDE;
++  virtual void SetScrollOffsetPinning(
++      bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE;
++  virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
++  virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
++  virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
++  virtual bool LockMouse() OVERRIDE;
++  virtual void UnlockMouse() OVERRIDE;
++  virtual void OnAccessibilityNotifications(
++      const std::vector<AccessibilityHostMsg_NotificationParams>& params)
++      OVERRIDE;
++
++  // ActiveWindowWatcherXObserver implementation.
++  virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
++
++  // IPC::Sender implementation:
++  virtual bool Send(IPC::Message* message) OVERRIDE;
++
++  void ModifyEventForEdgeDragging(GtkWidget* widget, GdkEventMotion* event);
++
++  void ModifyEventMovementAndCoords(WebKit::WebMouseEvent* event);
++
++  void Paint(const gfx::Rect&);
++
++  void ForwardKeyboardEvent(const NativeWebKeyboardEvent& event);
++
++  bool RetrieveSurrounding(std::string* text, size_t* cursor_index);
++
++  // BrowserAccessibilityDelegate implementation.
++  virtual void SetAccessibilityFocus(int acc_obj_id) OVERRIDE;
++  virtual void AccessibilityDoDefaultAction(int acc_obj_id) OVERRIDE;
++  virtual void AccessibilityScrollToMakeVisible(
++      int acc_obj_id, gfx::Rect subfocus) OVERRIDE;
++  virtual void AccessibilityScrollToPoint(
++      int acc_obj_id, gfx::Point point) OVERRIDE;
++  virtual void AccessibilitySetTextSelection(
++      int acc_obj_id, int start_offset, int end_offset) OVERRIDE;
++  virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE;
++  virtual void FatalAccessibilityTreeError() OVERRIDE;
++
++  // Get the root of the AtkObject* tree for accessibility.
++  AtkObject* GetAccessible();
++
++ protected:
++  friend class RenderWidgetHostView;
++
++  // Should construct only via RenderWidgetHostView::CreateViewForWidget.
++  explicit RenderWidgetHostViewEfl(RenderWidgetHost* widget);
++
++ private:
++  // Returns whether the widget needs an input grab (GTK+ and X) to work
++  // properly.
++  bool NeedsInputGrab();
++
++  // Returns whether this render view is a popup (<select> dropdown or
++  // autocomplete window).
++  bool IsPopup() const;
++
++  // Do initialization needed by all InitAs*() methods.
++  void DoSharedInit(Evas_Object* parent);
++
++  // Do initialization needed just by InitAsPopup() and InitAsFullscreen().
++  // We move and resize |window| to |bounds| and show it and its contents.
++  void DoPopupOrFullscreenInit(GtkWindow* window, const gfx::Rect& bounds);
++
++  // Update the display cursor for the render view.
++  void ShowCurrentCursor();
++
++  // Cause the next query for the widget center to recompute the cached value.
++  void MarkCachedWidgetCenterStale();
++
++  void OnCreatePluginContainer(gfx::PluginWindowHandle id);
++  void OnDestroyPluginContainer(gfx::PluginWindowHandle id);
++
++  gfx::Point GetWidgetCenter();
++
++  // The model object.
++  RenderWidgetHostImpl* host_;
++
++  // This is true when we are currently painting and thus should handle extra
++  // paint requests by expanding the invalid rect rather than actually
++  // painting.
++  bool about_to_validate_and_paint_;
++
++  // This is the rectangle which we'll paint.
++  gfx::Rect invalid_rect_;
++
++  // Whether or not this widget is hidden.
++  bool is_hidden_;
++
++  // Whether we are currently loading.
++  bool is_loading_;
++
++  // The cursor for the page. This is passed up from the renderer.
++  WebCursor current_cursor_;
++
++  // The time at which this view started displaying white pixels as a result of
++  // not having anything to paint (empty backing store from renderer). This
++  // value returns true for is_null() if we are not recording whiteout times.
++  base::TimeTicks whiteout_start_time_;
++
++  // The time it took after this view was selected for it to be fully painted.
++  base::TimeTicks web_contents_switch_paint_time_;
++
++  // The native view of our parent widget.  Used only for popups.
++  Evas_Object* parent_;
++
++  // We ignore the first mouse release on popups so the popup will remain open.
++  bool is_popup_first_mouse_release_;
++
++  // Whether or not this widget's input context was focused before being
++  // shadowed by another widget. Used in OnGrabNotify() handler to track the
++  // focused state correctly.
++  bool was_imcontext_focused_before_grab_;
++
++  // True if we are responsible for creating an X grab. This will only be used
++  // for <select> dropdowns. It should be true for most such cases, but false
++  // for extension popups.
++  bool do_x_grab_;
++
++  // Is the widget fullscreen?
++  bool is_fullscreen_;
++
++  // Has the window ever been marked active? Only valid for fullscreen or
++  // popup windows.
++  bool made_active_;
++
++  // Used to record the last position of the mouse.
++  // While the mouse is locked, they store the last known position just as mouse
++  // lock was entered.
++  // Relative to the upper-left corner of the view.
++  gfx::Point unlocked_mouse_position_;
++  // Relative to the upper-left corner of the screen.
++  gfx::Point unlocked_global_mouse_position_;
++  // Last hidden cursor position. Relative to screen.
++  gfx::Point global_mouse_position_;
++  // Indicates when mouse motion is valid after the widget has moved.
++  bool mouse_has_been_warped_to_new_center_;
++  // Indicates the cursor has been warped to the unlocked position,
++  // but a move event has not yet been received for it there.
++  bool mouse_is_being_warped_to_unlocked_position_;
++
++  // For full-screen windows we have a OnDestroy handler that we need to remove,
++  // so we keep it ID here.
++  unsigned long destroy_handler_id_;
++
++  gfx::Size requested_size_;
++
++  // The latest reported center of the widget, use GetWidgetCenter() to access.
++  gfx::Point widget_center_;
++  // If the window moves the widget_center will not be valid until we recompute.
++  bool widget_center_valid_;
++
++  // The number of times the user has dragged against horizontal edge  of the
++  // monitor (if the widget is aligned with that edge). Negative values
++  // indicate the left edge, positive the right.
++  int dragged_at_horizontal_edge_;
++
++  // The number of times the user has dragged against vertical edge  of the
++  // monitor (if the widget is aligned with that edge). Negative values
++  // indicate the top edge, positive the bottom.
++  int dragged_at_vertical_edge_;
++
++  gfx::PluginWindowHandle compositing_surface_;
++
++  gfx::PreserveWindow* preserve_window_;
++
++  scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
++};
++
++}  // namespace content
++
++#endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
+diff --git a/content/browser/renderer_host/window_utils_efl.cc b/content/browser/renderer_host/window_utils_efl.cc
+new file mode 100644
+index 0000000..1c6c511
+--- /dev/null
++++ b/content/browser/renderer_host/window_utils_efl.cc
+@@ -0,0 +1,51 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/browser/renderer_host/window_utils_efl.h"
++
++#include "ui/gfx/rect.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
++
++#include <Ecore_X.h>
++
++namespace content {
++
++namespace {
++
++// Length of an inch in CSS's 1px unit.
++const int kPixelsPerInch = 96;
++
++int depthPerComponent(int depth)
++{
++    switch (depth) {
++    case 0:
++    case 24:
++    case 32:
++        return 8;
++    case 8:
++        return 2;
++    default:
++        return depth / 3;
++    }
++}
++
++}
++
++void GetScreenInfoEfl(WebKit::WebScreenInfo* results)
++{
++  Ecore_X_Display* display = ecore_x_display_get();
++  Ecore_X_Screen* screen = ecore_x_default_screen_get();
++  int width, height;
++  ecore_x_screen_size_get(screen, &width, &height);
++  int depth = ecore_x_default_depth_get(display, screen);
++  results->deviceScaleFactor = ecore_x_dpi_get() / kPixelsPerInch;
++  results->isMonochrome = depth == 1;
++  results->depth = depth;
++  results->depthPerComponent = depthPerComponent(depth);
++  // FIXME: not sure how to get available rect.
++  results->rect = WebKit::WebRect(0, 0, width, height);
++  results->availableRect = results->rect;
++}
++
++} // namespace content
+diff --git a/content/browser/renderer_host/window_utils_efl.h b/content/browser/renderer_host/window_utils_efl.h
+new file mode 100644
+index 0000000..1df0e51
+--- /dev/null
++++ b/content/browser/renderer_host/window_utils_efl.h
+@@ -0,0 +1,20 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
++#define CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
++
++#include "content/common/content_export.h"
++
++namespace WebKit {
++struct WebScreenInfo;
++}
++
++namespace content {
++
++CONTENT_EXPORT void GetScreenInfoEfl(WebKit::WebScreenInfo* results);
++
++}  // namespace content
++
++#endif  // CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index a3a4196..1e2edb8 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -89,17 +89,15 @@ WebContentsViewEfl::WebContentsViewEfl(
+     WebContentsImpl* web_contents,
+     WebContentsViewDelegate* delegate)
+     : web_contents_(web_contents),
+-      delegate_(delegate) {
++      delegate_(delegate),
++      view_container_box_(0) {
+ }
+ WebContentsViewEfl::~WebContentsViewEfl() {
+ }
+ gfx::NativeView WebContentsViewEfl::GetNativeView() const {
+-  if (delegate_)
+-    return delegate_->GetNativeView();
+-
+-  return 0;
++  return GetContentNativeView();
+ }
+ gfx::NativeView WebContentsViewEfl::GetContentNativeView() const {
+@@ -173,7 +171,7 @@ RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
+   RenderWidgetHostView* view =
+       RenderWidgetHostView::CreateViewForWidget(render_widget_host);
+-  view->InitAsChild(NULL);
++  view->InitAsChild(reinterpret_cast<gfx::NativeView>(view_container_box_));
+   if (render_widget_host->IsRenderView()) {
+     RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
+     if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
+diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
+index 495d4ff..3c6d2f6 100644
+--- a/content/browser/web_contents/web_contents_view_efl.h
++++ b/content/browser/web_contents/web_contents_view_efl.h
+@@ -80,6 +80,8 @@ class CONTENT_EXPORT WebContentsViewEfl
+   virtual void GotFocus() OVERRIDE;
+   virtual void TakeFocus(bool reverse) OVERRIDE;
++  void SetViewContainerBox(Evas_Object* container_box) { view_container_box_ = container_box; }
++
+  private:
+   void UpdateDragDest(RenderViewHost* new_host);
+@@ -87,6 +89,10 @@ class CONTENT_EXPORT WebContentsViewEfl
+   scoped_ptr<WebContentsViewDelegate> delegate_;
++  Evas_Object* view_container_box_;
++
++  // The size we want the view to be.  We keep this in a separate variable
++  // because resizing in GTK+ is async.
+   gfx::Size requested_size_;
+   DISALLOW_COPY_AND_ASSIGN(WebContentsViewEfl);
+diff --git a/content/content_browser.gypi b/content/content_browser.gypi
+index d087938..3d881a2 100644
+--- a/content/content_browser.gypi
++++ b/content/content_browser.gypi
+@@ -827,6 +827,8 @@
+     'browser/renderer_host/render_widget_host_view_aura.h',
+     'browser/renderer_host/render_widget_host_view_base.cc',
+     'browser/renderer_host/render_widget_host_view_base.h',
++    'browser/renderer_host/render_widget_host_view_efl.cc',
++    'browser/renderer_host/render_widget_host_view_efl.h',
+     'browser/renderer_host/render_widget_host_view_gtk.cc',
+     'browser/renderer_host/render_widget_host_view_gtk.h',
+     'browser/renderer_host/render_widget_host_view_guest.cc',
+@@ -870,6 +872,8 @@
+     'browser/renderer_host/web_input_event_aura.h',
+     'browser/renderer_host/web_input_event_aurawin.cc',
+     'browser/renderer_host/web_input_event_aurax11.cc',
++    'browser/renderer_host/window_utils_efl.h',
++    'browser/renderer_host/window_utils_efl.cc',
+     'browser/resolve_proxy_msg_helper.cc',
+     'browser/resolve_proxy_msg_helper.h',
+     'browser/resource_context_impl.cc',
+@@ -1172,6 +1176,10 @@
+       'sources/': [
+         ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
+         ['exclude', 'browser/web_contents/web_contents_view_gtk.h'],
++        ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.cc'],
++        ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.h'],
++        ['exclude', 'browser/renderer_host/gtk_im_context_wrapper.cc'],
++        ['exclude', 'browser/renderer_host/gtk_im_context_wrapper.h'],
+       ]
+     }],
+     ['OS=="linux"', {
+diff --git a/content/content_shell.gypi b/content/content_shell.gypi
+index fc8b680..7ce351f 100644
+--- a/content/content_shell.gypi
++++ b/content/content_shell.gypi
+@@ -137,6 +137,7 @@
+         'shell/shell_web_contents_view_delegate_android.cc',
+         'shell/shell_web_contents_view_delegate_creator.h',
+         'shell/shell_web_contents_view_delegate_gtk.cc',
++        'shell/shell_web_contents_view_delegate_efl.cc',
+         'shell/shell_web_contents_view_delegate_mac.mm',
+         'shell/shell_web_contents_view_delegate_win.cc',
+         'shell/shell_web_contents_view_delegate.h',
+@@ -222,6 +223,7 @@
+           ],
+           'sources/': [
+             ['exclude', 'shell/shell_gtk.cc'],
++            ['exclude', 'shell/shell_web_contents_view_delegate_gtk.cc'],
+           ],
+         }],
+         ['chromeos==1', {
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+index 19822da..3078d63 100644
+--- a/content/shell/shell_efl.cc
++++ b/content/shell/shell_efl.cc
+@@ -16,6 +16,7 @@
+ #include "content/public/browser/native_web_keyboard_event.h"
+ #include "content/public/browser/web_contents.h"
+ #include "content/public/browser/web_contents_view.h"
++#include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/common/renderer_preferences.h"
+ #include "content/shell/shell_browser_context.h"
+ #include "content/shell/shell_content_browser_client.h"
+@@ -51,22 +52,11 @@ void Shell::PlatformCreateWindow(int width, int height) {
+   if (headless_)
+     return;
+-  main_window_ = elm_win_add(NULL, "Content Shell", ELM_WIN_BASIC);
+-
+-  elm_win_title_set(main_window_, "Content Shell");
++  main_window_ = elm_win_util_standard_add("Content Shell", "Content Shell");
+   elm_win_autodel_set(main_window_, true);
+-
+   evas_object_resize(main_window_, width, height);
+   evas_object_event_callback_add(main_window_, EVAS_CALLBACK_DEL,
+                                  OnMainWindowDel, this);
+-
+-  Evas_Object* rect = evas_object_rectangle_add(
+-      evas_object_evas_get(main_window_));
+-  evas_object_color_set(rect, 255, 0, 0, 255);
+-  evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_win_resize_object_add(main_window_, rect);
+-  evas_object_show(rect);
+-
+   evas_object_show(main_window_);
+ }
+@@ -74,7 +64,13 @@ void Shell::PlatformSetContents() {
+   if (headless_)
+     return;
++  Evas_Object* view_box = elm_box_add(main_window_);
++  evas_object_size_hint_weight_set(view_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++
++  elm_win_resize_object_add(main_window_, view_box);
++
+   WebContentsView* content_view = web_contents_->GetView();
++  static_cast<WebContentsViewEfl*>(content_view)->SetViewContainerBox(view_box);
+ }
+ void Shell::SizeTo(int width, int height) {
+diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
+index 283f37f..db6a785 100644
+--- a/content/shell/shell_web_contents_view_delegate.h
++++ b/content/shell/shell_web_contents_view_delegate.h
+@@ -53,7 +53,7 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+   WebContents* web_contents_;
+   ContextMenuParams params_;
+-#if defined(TOOLKIT_GTK)
++#if defined(TOOLKIT_GTK) && !defined(TOOLKIT_EFL)
+   ui::OwnedWidgetGtk floating_;
+   GtkWidget* expanded_container_;
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+new file mode 100644
+index 0000000..9e10940
+--- /dev/null
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -0,0 +1,71 @@
++// Copyright (c) 2013 Intel. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/shell/shell_web_contents_view_delegate.h"
++
++#include "base/command_line.h"
++#include "content/public/browser/render_process_host.h"
++#include "content/public/browser/render_view_host.h"
++#include "content/public/browser/render_widget_host_view.h"
++#include "content/public/browser/web_contents.h"
++#include "content/public/browser/web_contents_view.h"
++#include "content/public/common/context_menu_params.h"
++#include "content/shell/shell.h"
++#include "content/shell/shell_browser_context.h"
++#include "content/shell/shell_browser_main_parts.h"
++#include "content/shell/shell_content_browser_client.h"
++#include "content/shell/shell_devtools_frontend.h"
++#include "content/shell/shell_switches.h"
++#include "content/shell/shell_web_contents_view_delegate_creator.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
++#include "ui/base/gtk/focus_store_gtk.h"
++#include "ui/base/gtk/gtk_floating_container.h"
++
++using WebKit::WebContextMenuData;
++
++namespace content {
++
++WebContentsViewDelegate* CreateShellWebContentsViewDelegate(
++    WebContents* web_contents) {
++  return new ShellWebContentsViewDelegate(web_contents);
++}
++
++ShellWebContentsViewDelegate::ShellWebContentsViewDelegate(
++    WebContents* web_contents)
++    : web_contents_(web_contents) {
++}
++
++ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() {
++}
++
++void ShellWebContentsViewDelegate::ShowContextMenu(
++    const ContextMenuParams& params,
++    ContextMenuSourceType type) {
++  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
++    return;
++}
++
++WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
++  return NULL;
++}
++
++void ShellWebContentsViewDelegate::Initialize(GtkWidget* expanded_container,
++                                              ui::FocusStoreGtk* focus_store) {
++}
++
++gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const {
++  return 0;
++}
++
++void ShellWebContentsViewDelegate::Focus() {
++}
++
++gboolean ShellWebContentsViewDelegate::OnNativeViewFocusEvent(
++    GtkWidget* widget,
++    GtkDirectionType type,
++    gboolean* return_value) {
++  return false;
++}
++
++}  // namespace content
+diff --git a/ui/gfx/efl_util.cc b/ui/gfx/efl_util.cc
+index 7cd7cb4..e207949 100644
+--- a/ui/gfx/efl_util.cc
++++ b/ui/gfx/efl_util.cc
+@@ -18,12 +18,14 @@ void EflInit() {
+   evas_init();
+   ecore_init();
+   ecore_evas_init();
++  ecore_x_init(NULL);
+   edje_init();
+   ecore_main_loop_glib_integrate();
+ }
+ void EflShutdown() {
+   edje_shutdown();
++  ecore_x_shutdown();
+   ecore_evas_shutdown();
+   ecore_shutdown();
+   evas_shutdown();
+diff --git a/ui/gfx/preserve_window_delegate_efl.h b/ui/gfx/preserve_window_delegate_efl.h
+new file mode 100644
+index 0000000..aa7863b
+--- /dev/null
++++ b/ui/gfx/preserve_window_delegate_efl.h
+@@ -0,0 +1,47 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
++#define UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
++
++#include <Evas.h>
++
++#include "ui/base/ui_export.h"
++#include "ui/gfx/point.h"
++#include "ui/gfx/rect.h"
++#include "ui/gfx/size.h"
++
++namespace gfx {
++
++// A private interface used by RootWindowHost implementations to communicate input events
++// with their owning PreserveWindow.
++class UI_EXPORT PreserveWindowDelegate {
++ public:
++  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) = 0;
++  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) = 0;
++  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) = 0;
++  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) = 0;
++  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event) = 0;
++  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event) = 0;
++
++  // Called when the windowing system activates the window.
++  virtual void PreserveWindowFocusIn() = 0;
++
++  // Called when system focus is changed to another window.
++  virtual void PreserveWindowFocusOut() = 0;
++
++  virtual void PreserveWindowShow() = 0;
++  virtual void PreserveWindowHide() = 0;
++
++  virtual void PreserveWindowMove(const gfx::Point& origin) = 0;
++  virtual void PreserveWindowResize(const gfx::Size& size) = 0;
++  virtual void PreserveWindowRepaint(const gfx::Rect& damage_rect) = 0;
++
++ protected:
++  virtual ~PreserveWindowDelegate() {}
++};
++
++}  // namespace gfx
++
++#endif  // UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+new file mode 100644
+index 0000000..4601099
+--- /dev/null
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -0,0 +1,421 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/gfx/preserve_window_efl.h"
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Ecore_X.h>
++#include <Elementary.h>
++
++#include "base/logging.h"
++#include "ui/gfx/point.h"
++#include "ui/gfx/rect.h"
++#include "ui/gfx/size.h"
++
++namespace gfx {
++
++namespace {
++#define evas_smart_preserve_window_type "Evas_Smart_Preserve_Window"
++
++const char PRESERVE_WINDOW_MOVE[] = "preserve,moved";
++const char PRESERVE_WINDOW_RESIZE[] = "preserve,resized";
++const char PRESERVE_WINDOW_REPAINT[] = "preserve,repainted";
++const Evas_Smart_Cb_Description g_smart_callbacks[] = {
++    {PRESERVE_WINDOW_MOVE, "(ii)"},
++    {PRESERVE_WINDOW_RESIZE, "(ii)"},
++    {PRESERVE_WINDOW_REPAINT, "(iiii)"},
++    {NULL, NULL}};
++
++enum PreserveWindowSmartEventType {
++  PreserveWindowMoveType,
++  PreserveWindowResizeType,
++  PreserveWindowRepaintType,
++};
++
++const char* PreserveWindowSmartEvent(PreserveWindowSmartEventType type) {
++  switch (type) {
++    case PreserveWindowMoveType:
++      return PRESERVE_WINDOW_MOVE;
++      break;
++    case PreserveWindowResizeType:
++      return PRESERVE_WINDOW_RESIZE;
++      break;
++    case PreserveWindowRepaintType:
++      return PRESERVE_WINDOW_REPAINT;
++      break;
++  }
++  NOTREACHED();
++  return "";
++}
++
++struct PreserveWindowData {
++  Evas_Object_Smart_Clipped_Data base;
++  Evas_Object* window_;
++  // FIXME (alexshalamov): It is dummy to receive input events.
++  // We must find proper event handling way.
++  Evas_Object* background_;
++};
++
++bool IsPreserveWindowEvasObject(const Evas_Object* evas_object) {
++    DCHECK(evas_object);
++
++    const char* evas_object_type = evas_object_type_get(evas_object);
++    if (!evas_object_smart_type_check(evas_object,
++                                      evas_smart_preserve_window_type)) {
++      LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
++        return false;
++    }
++
++    const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
++    if (!evas_smart) {
++        LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
++        return false;
++    }
++
++    const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
++    if (!smart_class) {
++      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
++        return false;
++    }
++
++    return true;
++}
++
++inline PreserveWindowData* ToSmartData(Evas_Object* evas_object) {
++  DCHECK(evas_object);
++  DCHECK(IsPreserveWindowEvasObject(evas_object));
++  CHECK(evas_object_smart_data_get(evas_object));
++  return static_cast<PreserveWindowData*>(evas_object_smart_data_get(evas_object));
++}
++
++EVAS_SMART_SUBCLASS_NEW(evas_smart_preserve_window_type,
++                        evas_smart_preserve_window,
++                        Evas_Smart_Class,
++                        Evas_Smart_Class,
++                        evas_object_smart_clipped_class_get,
++                        g_smart_callbacks);
++
++/* create and setup a new preserve window smart object's internals */
++void evas_smart_preserve_window_smart_add(Evas_Object* o) {
++  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
++  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
++  PreserveWindowData* smart_data;
++  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
++  if (!smart_data) {
++    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
++    if (!smart_data) {
++      return;
++    }
++    evas_object_smart_data_set(o, smart_data);
++  }
++
++  int x, y, w, h = 0;
++  evas_object_geometry_get(o, &x, &y, &w, &h);
++
++  smart_data->window_ = elm_win_add(o, "preserve-window", ELM_WIN_DOCK);
++  evas_object_resize(smart_data->window_, w, h);
++  evas_object_show(smart_data->window_);
++
++  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
++  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
++  ecore_x_window_reparent(x_window, root_x_window, x, y);
++
++  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(smart_data->window_));
++  evas_object_color_set(smart_data->background_, 0, 0, 0, 0);
++  evas_object_size_hint_weight_set(smart_data->background_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  elm_win_resize_object_add(smart_data->window_, smart_data->background_);
++  evas_object_focus_set(smart_data->background_, EINA_TRUE);
++  evas_smart_preserve_window_parent_sc->add(o);
++}
++
++void evas_smart_preserve_window_smart_del(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
++  ecore_x_window_reparent(x_window, 0 /* default root window */, 0 /* x */, 0 /* y */);
++  evas_object_del(smart_data->background_);
++  evas_object_del(smart_data->window_);
++  evas_smart_preserve_window_parent_sc->del(o);
++}
++
++void evas_smart_preserve_window_smart_show(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  evas_object_show(smart_data->window_);
++  evas_object_show(smart_data->background_);
++  evas_smart_preserve_window_parent_sc->show(o);
++}
++
++void evas_smart_preserve_window_smart_hide(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  evas_object_hide(smart_data->window_);
++  evas_object_hide(smart_data->background_);
++  evas_smart_preserve_window_parent_sc->hide(o);
++}
++
++void evas_smart_preserve_window_smart_move(Evas_Object* o,
++                                           Evas_Coord x,
++                                           Evas_Coord y) {
++  Evas_Coord ox, oy;
++  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
++  if ((ox == x) && (oy == y))
++    return;
++
++  PreserveWindowData* smart_data = ToSmartData(o);
++  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
++  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
++  ecore_x_window_reparent(x_window, root_x_window, x, y);
++
++  int position[2] = {x, y};
++  evas_object_smart_callback_call(
++      o, PRESERVE_WINDOW_MOVE, static_cast<void*>(position));
++
++  /* this will trigger recalculation */
++  evas_object_smart_changed(o);
++}
++
++void evas_smart_preserve_window_smart_resize(Evas_Object* o,
++                                             Evas_Coord w,
++                                             Evas_Coord h) {
++  Evas_Coord ow, oh;
++  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
++  if ((ow == w) && (oh == h))
++    return;
++
++  PreserveWindowData* smart_data = ToSmartData(o);
++  evas_object_resize(smart_data->window_, w, h);
++
++  int size[2] = {w, h};
++  evas_object_smart_callback_call(
++      o, PRESERVE_WINDOW_RESIZE, static_cast<void*>(size));
++
++  /* this will trigger recalculation */
++  evas_object_smart_changed(o);
++}
++
++/* act on child objects' properties, before rendering */
++void evas_smart_preserve_window_smart_calculate(Evas_Object* o) {
++  int dirty_rect[4] = { 0, };
++  // FIXME: how to know dirty rect actually.
++  evas_object_geometry_get(o, &dirty_rect[0], &dirty_rect[1], &dirty_rect[2], &dirty_rect[3]);
++  evas_object_smart_callback_call(
++      o, PRESERVE_WINDOW_REPAINT, static_cast<void*>(dirty_rect));
++}
++
++/* setting our smart interface */
++void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
++  /* specializing these two */
++  sc->add = evas_smart_preserve_window_smart_add;
++  sc->del = evas_smart_preserve_window_smart_del;
++  sc->show = evas_smart_preserve_window_smart_show;
++  sc->hide = evas_smart_preserve_window_smart_hide;
++
++  /* clipped smart object has no hook on move, resize and calculation */
++  sc->move = evas_smart_preserve_window_smart_move;
++  sc->resize = evas_smart_preserve_window_smart_resize;
++  sc->calculate = evas_smart_preserve_window_smart_calculate;
++}
++
++// SmartObjectEventHandler implementation.
++template <Evas_Callback_Type EventType> class SmartObjectEventHandler {
++ public:
++  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
++    evas_object_event_callback_add(evas_object, EventType, HandleEvent, delegate);
++  }
++
++  static void Unsubscribe(Evas_Object* evas_object) {
++    evas_object_event_callback_del(evas_object, EventType, HandleEvent);
++  }
++
++  static void HandleEvent(void* data, Evas*, Evas_Object*, void* event_info);
++};
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowMouseDown(static_cast<Evas_Event_Mouse_Down*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowMouseUp(static_cast<Evas_Event_Mouse_Up*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowMouseMove(static_cast<Evas_Event_Mouse_Move*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowMouseWheel(static_cast<Evas_Event_Mouse_Wheel*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowKeyDown(static_cast<Evas_Event_Key_Down*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowKeyUp(static_cast<Evas_Event_Key_Up*>(event_info));
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void*) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowFocusIn();
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void*) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowFocusOut();
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void*) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowShow();
++}
++
++template <>
++void SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::HandleEvent(
++    void* data, Evas*, Evas_Object*, void*) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  delegate->PreserveWindowHide();
++}
++
++// SmartObjectSmartHandler implementation.
++template <PreserveWindowSmartEventType EventType> class SmartObjectSmartHandler {
++ public:
++  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
++    evas_object_smart_callback_add(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
++                                   HandleEventMove, delegate);
++    evas_object_smart_callback_add(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
++                                   HandleEventResize, delegate);
++    evas_object_smart_callback_add(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
++                                   HandleEventRepaint, delegate);
++  }
++
++  static void Unsubscribe(Evas_Object* evas_object) {
++    evas_object_smart_callback_del(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
++                                   HandleEventMove);
++    evas_object_smart_callback_del(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
++                                   HandleEventResize);
++    evas_object_smart_callback_del(evas_object,
++                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
++                                   HandleEventRepaint);
++  }
++
++  static void HandleEventMove(void* data, Evas_Object*, void* event_info);
++  static void HandleEventResize(void* data, Evas_Object*, void* event_info);
++  static void HandleEventRepaint(void* data, Evas_Object*, void* event_info);
++};
++
++template <PreserveWindowSmartEventType EventType>
++void SmartObjectSmartHandler<EventType>::HandleEventMove(
++    void* data, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  int* position = static_cast<int*>(event_info);
++  delegate->PreserveWindowMove(gfx::Point(position[0], position[1]));
++}
++
++template <PreserveWindowSmartEventType EventType>
++void SmartObjectSmartHandler<EventType>::HandleEventResize(
++    void* data, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  int* size = static_cast<int*>(event_info);
++  delegate->PreserveWindowResize(gfx::Size(size[0], size[1]));
++}
++
++template <PreserveWindowSmartEventType EventType>
++void SmartObjectSmartHandler<EventType>::HandleEventRepaint(
++    void* data, Evas_Object*, void* event_info) {
++  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
++  int* dirty_rect = static_cast<int*>(event_info);
++  delegate->PreserveWindowRepaint(gfx::Rect(dirty_rect[0],
++                                            dirty_rect[1],
++                                            dirty_rect[2],
++                                            dirty_rect[3]));
++}
++
++}  // namespace
++
++// static
++PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
++                                       Evas* evas) {
++  return new PreserveWindow(delegate, evas);
++}
++
++PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
++    : delegate_(delegate) {
++  smart_object_ = evas_object_smart_add(evas, evas_smart_preserve_window_smart_class_new());
++  evas_object_show(smart_object_);
++
++  SmartObjectSmartHandler<PreserveWindowMoveType>::Subscribe(smart_object_, delegate_);
++  SmartObjectSmartHandler<PreserveWindowResizeType>::Subscribe(smart_object_, delegate_);
++  SmartObjectSmartHandler<PreserveWindowRepaintType>::Subscribe(smart_object_, delegate_);
++
++  PreserveWindowData* smart_data = ToSmartData(smart_object_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background_, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background_, delegate_);
++
++  // FIXME: After creation, request redraw.
++  evas_object_smart_changed(smart_object_);
++}
++
++PreserveWindow::~PreserveWindow() {
++  SmartObjectSmartHandler<PreserveWindowMoveType>::Unsubscribe(smart_object_);
++  SmartObjectSmartHandler<PreserveWindowResizeType>::Unsubscribe(smart_object_);
++  SmartObjectSmartHandler<PreserveWindowRepaintType>::Unsubscribe(smart_object_);
++
++  PreserveWindowData* smart_data = ToSmartData(smart_object_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Unsubscribe(smart_data->background_);
++  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Unsubscribe(smart_data->background_);
++
++  evas_object_del(smart_object_);
++}
++
++
++Evas_Object* PreserveWindow::EvasWindow() {
++  PreserveWindowData* smart_data = ToSmartData(smart_object_);
++  return smart_data->window_;
++}
++
++}  // namespace gfx
+diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
+new file mode 100644
+index 0000000..56a0b78
+--- /dev/null
++++ b/ui/gfx/preserve_window_efl.h
+@@ -0,0 +1,37 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef UI_GFX_PRESERVE_WINDOW_EFL_H_
++#define UI_GFX_PRESERVE_WINDOW_EFL_H_
++
++#include <Evas.h>
++
++#include "base/basictypes.h"
++#include "base/memory/scoped_ptr.h"
++#include "ui/base/ui_export.h"
++#include "ui/gfx/preserve_window_delegate_efl.h"
++
++namespace gfx {
++
++class UI_EXPORT PreserveWindow {
++ public:
++  static PreserveWindow* Create(PreserveWindowDelegate*, Evas*);
++
++  ~PreserveWindow();
++
++  Evas_Object* SmartObject() const { return smart_object_; }
++  Evas_Object* EvasWindow();
++
++ private:
++  PreserveWindow(PreserveWindowDelegate*, Evas*);
++
++  PreserveWindowDelegate* delegate_;
++  Evas_Object* smart_object_;
++
++  DISALLOW_COPY_AND_ASSIGN(PreserveWindow);
++};
++
++}  // namespace gfx
++
++#endif  // UI_GFX_PRESERVE_WINDOW_EFL_H_
+diff --git a/ui/gfx/screen_efl.cc b/ui/gfx/screen_efl.cc
+new file mode 100644
+index 0000000..8bf4f16
+--- /dev/null
++++ b/ui/gfx/screen_efl.cc
+@@ -0,0 +1,87 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/gfx/screen.h"
++
++#include <Ecore_X.h>
++#include <Ecore_Evas.h>
++
++#include "base/logging.h"
++#include "ui/gfx/display.h"
++
++namespace {
++
++class ScreenEfl : public gfx::Screen {
++ public:
++  ScreenEfl() {
++  }
++
++  virtual ~ScreenEfl() {
++  }
++
++  virtual bool IsDIPEnabled() OVERRIDE {
++    return false;
++  }
++
++  virtual gfx::Point GetCursorScreenPoint() OVERRIDE {
++    return gfx::Point();
++  }
++
++  virtual gfx::NativeWindow GetWindowAtCursorScreenPoint() OVERRIDE {
++    NOTIMPLEMENTED();
++    return NULL;
++  }
++
++  virtual int GetNumDisplays() OVERRIDE {
++    return ecore_x_screen_count_get();
++  }
++
++  virtual gfx::Display GetDisplayNearestWindow(
++      gfx::NativeView view) const OVERRIDE {
++    return GetPrimaryDisplay();
++  }
++
++  virtual gfx::Display GetDisplayNearestPoint(
++      const gfx::Point& point) const OVERRIDE {
++    return GetPrimaryDisplay();
++  }
++
++  virtual gfx::Display GetDisplayMatching(
++      const gfx::Rect& match_rect) const OVERRIDE {
++    return GetPrimaryDisplay();
++  }
++
++  virtual gfx::Display GetPrimaryDisplay() const OVERRIDE {
++    static bool initialized = false;
++    if (!initialized) {
++      ecore_x_init(NULL);
++      initialized = true;
++    }
++
++    int width = 0, height = 0;
++    Ecore_X_Screen* screen = ecore_x_default_screen_get();
++    ecore_x_screen_size_get(screen, &width, &height);
++    // fprintf(stdout, "%dx%d\n", width, height);
++    return gfx::Display(0, gfx::Rect(width, height));
++  }
++
++  virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE {
++  }
++
++  virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE {
++  }
++
++ private:
++  DISALLOW_COPY_AND_ASSIGN(ScreenEfl);
++};
++
++}  // namespace
++
++namespace gfx {
++
++Screen* CreateNativeScreen() {
++  return new ScreenEfl;
++}
++
++} // namespace gfx
+diff --git a/ui/ui.gyp b/ui/ui.gyp
+index 797fd78..a7c9cbf 100644
+--- a/ui/ui.gyp
++++ b/ui/ui.gyp
+@@ -478,6 +478,9 @@
+         'gfx/point_conversions.h',
+         'gfx/point_f.cc',
+         'gfx/point_f.h',
++        'gfx/preserve_window_efl.cc',
++        'gfx/preserve_window_efl.h',
++        'gfx/preserve_window_delegate_efl.h',
+         'gfx/quad_f.cc',
+         'gfx/quad_f.h',
+         'gfx/rect.cc',
+@@ -698,8 +701,14 @@
+             '../build/linux/system.gyp:efl',
+           ],
+           'sources': [
++            'base/clipboard/clipboard_efl.cc',
++            'base/resource/resource_bundle_efl.cc',
+             'gfx/efl_util.cc',
+             'gfx/efl_util.h',
++            'gfx/screen_efl.cc',
++          ],
++          'sources!': [
++            'gfx/screen_gtk.cc',
+           ],
+         }],
+         ['chromeos==1 or (use_aura==1 and OS=="linux" and use_x11==0)', {
+-- 
+1.8.1.2
+
diff --git a/patchset/0003-Compiles-without-GTK.patch b/patchset/0003-Compiles-without-GTK.patch
new file mode 100644 (file)
index 0000000..4aa6505
--- /dev/null
@@ -0,0 +1,1591 @@
+From 7cf44677ae5acc86899ae3bae1fef8621bc8063f Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Thu, 27 Jun 2013 18:36:26 +0300
+Subject: [PATCH 03/33] Compiles without GTK.
+
+We exclude all gtk symbols and replace them with the corresponding EFL ones
+Make shell use gfx::NativeWindow
+
+Now that gfx::NativeWindow is set to Evas_Object*, we should just use window_.
+and remove Evas_Object* main_window_
+---
+ build/build_config.h                               |   2 +-
+ build/common.gypi                                  |   2 +-
+ content/browser/browser_main_loop.cc               |   2 +-
+ content/browser/gpu/gpu_process_host_ui_shim.cc    |   6 +-
+ content/browser/gpu/gpu_process_host_ui_shim.h     |   2 +-
+ .../renderer_host/native_web_keyboard_event_efl.cc |  28 +++
+ .../renderer_host/render_process_host_impl.cc      |   2 +-
+ .../renderer_host/render_widget_host_view_efl.cc   | 135 +------------
+ .../renderer_host/render_widget_host_view_efl.h    |  22 +--
+ content/browser/renderer_host/window_utils_efl.cc  |   6 +-
+ .../browser/web_contents/web_contents_view_efl.cc  |  73 +------
+ content/content_browser.gypi                       |   2 +
+ content/shell/shell.h                              |   4 -
+ content/shell/shell_efl.cc                         |  18 +-
+ content/shell/shell_web_contents_view_delegate.h   |   2 +-
+ .../shell/shell_web_contents_view_delegate_efl.cc  |  20 --
+ printing/printing.gyp                              |   5 +
+ printing/printing_context_efl.cc                   |  20 ++
+ ui/base/clipboard/clipboard.h                      |   1 +
+ ui/base/clipboard/clipboard_efl.cc                 | 219 +++++++++++++++++++++
+ ui/base/resource/resource_bundle_efl.cc            |  64 ++++++
+ ui/gfx/native_widget_types.h                       |  13 ++
+ ui/native_theme/native_theme.gyp                   |   1 +
+ ui/native_theme/native_theme_efl.cc                | 101 ++++++++++
+ ui/snapshot/snapshot.gyp                           |   1 +
+ ui/snapshot/snapshot_efl.cc                        |  27 +++
+ ui/surface/transport_dib.h                         |   8 +-
+ ui/surface/transport_dib_posix.cc                  |   2 +-
+ ui/surface/transport_dib_sysvipc.cc                |   2 +-
+ ui/ui.gyp                                          |  17 +-
+ webkit/glue/webcursor_efl.cc                       |  35 ++++
+ webkit/glue/webkit_glue.gypi                       |   2 +
+ .../plugins/npapi/webplugin_delegate_impl_efl.cc   |  85 ++++++++
+ 33 files changed, 656 insertions(+), 273 deletions(-)
+ create mode 100644 content/browser/renderer_host/native_web_keyboard_event_efl.cc
+ create mode 100644 printing/printing_context_efl.cc
+ create mode 100644 ui/base/clipboard/clipboard_efl.cc
+ create mode 100644 ui/base/resource/resource_bundle_efl.cc
+ create mode 100644 ui/native_theme/native_theme_efl.cc
+ create mode 100644 ui/snapshot/snapshot_efl.cc
+ create mode 100644 webkit/glue/webcursor_efl.cc
+ create mode 100644 webkit/plugins/npapi/webplugin_delegate_impl_efl.cc
+
+diff --git a/build/build_config.h b/build/build_config.h
+index dd7443e..040ec88 100644
+--- a/build/build_config.h
++++ b/build/build_config.h
+@@ -32,7 +32,7 @@
+ #define OS_LINUX 1
+ // Use TOOLKIT_GTK on linux if TOOLKIT_VIEWS isn't defined.
+ #if !defined(TOOLKIT_VIEWS) && defined(USE_X11)
+-#define TOOLKIT_GTK
++// #define TOOLKIT_GTK  // Mikhail FIXME : find a proper way here!
+ #define TOOLKIT_EFL
+ #endif
+ #elif defined(_WIN32)
+diff --git a/build/common.gypi b/build/common.gypi
+index 9753413..a769a1f 100644
+--- a/build/common.gypi
++++ b/build/common.gypi
+@@ -139,7 +139,7 @@
+           # Set toolkit_uses_gtk for the Chromium browser on Linux.
+           ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_aura==0 and use_ozone==0', {
+             'toolkit_uses_efl%': 1,
+-            'toolkit_uses_gtk%': 1,
++            'toolkit_uses_gtk%': 0,
+           }, {
+             'toolkit_uses_efl%': 0,
+             'toolkit_uses_gtk%': 0,
+diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
+index 37cdf9c..7f88b44 100644
+--- a/content/browser/browser_main_loop.cc
++++ b/content/browser/browser_main_loop.cc
+@@ -835,7 +835,7 @@ void BrowserMainLoop::InitializeToolkit() {
+   g_type_init();
+ #endif
+-#if !defined(USE_AURA)
++#if !defined(USE_AURA) && !defined(TOOLKIT_EFL)
+   gfx::GtkInitFromCommandLine(parsed_command_line_);
+ #endif
+diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
+index a243115..0bf8df0 100644
+--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
++++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
+@@ -211,7 +211,7 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
+                         OnUpdateVSyncParameters)
+     IPC_MESSAGE_HANDLER(GpuHostMsg_FrameDrawn, OnFrameDrawn)
+-#if defined(TOOLKIT_GTK) || defined(OS_WIN)
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || defined(OS_WIN)
+     IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView)
+ #endif
+@@ -256,7 +256,7 @@ void GpuProcessHostUIShim::OnGraphicsInfoCollected(const GPUInfo& gpu_info) {
+   GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
+ }
+-#if defined(TOOLKIT_GTK) || defined(OS_WIN)
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || defined(OS_WIN)
+ void GpuProcessHostUIShim::OnResizeView(int32 surface_id,
+                                         int32 route_id,
+@@ -286,6 +286,8 @@ void GpuProcessHostUIShim::OnResizeView(int32 surface_id,
+     gdk_window_resize(window, size.width(), size.height());
+     XSync(display, False);
+   }
++#elif defined(TOOLKIT_EFL)
++  (void)surface; // FIXME : Resize the window?
+ #elif defined(OS_WIN)
+   // Ensure window does not have zero area because D3D cannot create a zero
+   // area swap chain.
+diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h
+index 243cfd17..79468cf 100644
+--- a/content/browser/gpu/gpu_process_host_ui_shim.h
++++ b/content/browser/gpu/gpu_process_host_ui_shim.h
+@@ -87,7 +87,7 @@ class GpuProcessHostUIShim : public IPC::Listener,
+   void OnLogMessage(int level, const std::string& header,
+       const std::string& message);
+-#if defined(TOOLKIT_GTK) || defined(OS_WIN)
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || defined(OS_WIN)
+   void OnResizeView(int32 surface_id,
+                     int32 route_id,
+                     gfx::Size size);
+diff --git a/content/browser/renderer_host/native_web_keyboard_event_efl.cc b/content/browser/renderer_host/native_web_keyboard_event_efl.cc
+new file mode 100644
+index 0000000..78b258a
+--- /dev/null
++++ b/content/browser/renderer_host/native_web_keyboard_event_efl.cc
+@@ -0,0 +1,28 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "content/public/browser/native_web_keyboard_event.h"
++
++#include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
++
++namespace content {
++
++NativeWebKeyboardEvent::NativeWebKeyboardEvent() {
++}
++
++NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event) {
++}
++
++NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent&) {
++}
++
++NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
++    const NativeWebKeyboardEvent& other) {
++  return *this;
++}
++
++NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {
++}
++
++}  // namespace content
+diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
+index a3b6db6..6db7eaf 100644
+--- a/content/browser/renderer_host/render_process_host_impl.cc
++++ b/content/browser/renderer_host/render_process_host_impl.cc
+@@ -1032,7 +1032,7 @@ TransportDIB* RenderProcessHostImpl::MapTransportDIB(
+                   STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
+                   FALSE, 0);
+   return TransportDIB::Map(section);
+-#elif defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA))
++#elif defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || (defined(OS_LINUX) && defined(USE_AURA))
+   return TransportDIB::Map(dib_id.shmkey);
+ #elif defined(OS_ANDROID)
+   return TransportDIB::Map(dib_id);
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 86fe664..9118002 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -26,9 +26,6 @@
+ #include "base/strings/utf_offset_string_conversions.h"
+ #include "base/time.h"
+ #include "base/utf_string_conversions.h"
+-#include "content/browser/accessibility/browser_accessibility_gtk.h"
+-#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
+-#include "content/browser/renderer_host/backing_store_gtk.h"
+ #include "content/browser/renderer_host/render_view_host_delegate.h"
+ #include "content/browser/renderer_host/render_view_host_impl.h"
+ #include "content/browser/renderer_host/window_utils_efl.h"
+@@ -40,24 +37,20 @@
+ #include "skia/ext/platform_canvas.h"
+ #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+ #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
+-#include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
+ #include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
+ #include "ui/base/clipboard/scoped_clipboard_writer.h"
+-#include "ui/base/gtk/gtk_compat.h"
+ #include "ui/base/text/text_elider.h"
+ #include "ui/base/x/active_window_watcher_x.h"
+ #include "ui/base/x/x11_util.h"
+ #include "ui/gfx/preserve_window_efl.h"
+-#include "webkit/glue/webcursor_gtk_data.h"
+ #include "webkit/plugins/npapi/webplugin.h"
+-using WebKit::WebInputEventFactory;
+ using WebKit::WebMouseWheelEvent;
+ using WebKit::WebScreenInfo;
+ namespace content {
+-namespace {
++namespace {
+ // Paint rects on Linux are bounded by the maximum size of a shared memory
+ // region. By default that's 32MB, but many distros increase it significantly
+ // (i.e. to 256MB).
+@@ -75,31 +68,6 @@ const int kMaxWindowHeight = 10000;
+ // scroll size for linux.
+ const float kDefaultScrollPixelsPerTick = 160.0f / 3.0f;
+-const GdkColor kBGColor =
+-#if defined(NDEBUG)
+-  { 0, 0xff * 257, 0xff * 257, 0xff * 257 };
+-#else
+-  { 0, 0x00 * 257, 0xff * 257, 0x00 * 257 };
+-#endif
+-
+-// Returns the spinning cursor used for loading state.
+-GdkCursor* GetMozSpinningCursor() {
+-  static GdkCursor* moz_spinning_cursor = NULL;
+-  if (!moz_spinning_cursor) {
+-    const GdkColor fg = { 0, 0, 0, 0 };
+-    const GdkColor bg = { 65535, 65535, 65535, 65535 };
+-    GdkPixmap* source = gdk_bitmap_create_from_data(
+-        NULL, reinterpret_cast<const gchar*>(moz_spinning_bits), 32, 32);
+-    GdkPixmap* mask = gdk_bitmap_create_from_data(
+-        NULL, reinterpret_cast<const gchar*>(moz_spinning_mask_bits), 32, 32);
+-    moz_spinning_cursor =
+-        gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
+-    g_object_unref(source);
+-    g_object_unref(mask);
+-  }
+-  return moz_spinning_cursor;
+-}
+-
+ bool MovedToPoint(const WebKit::WebMouseEvent& mouse_event,
+                    const gfx::Point& center) {
+   return mouse_event.globalX == center.x() &&
+@@ -295,9 +263,6 @@ bool RenderWidgetHostViewEfl::HasFocus() const {
+   return true;
+ }
+-void RenderWidgetHostViewEfl::ActiveWindowChanged(GdkWindow* window) {
+-}
+-
+ bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
+   return host_->Send(message);
+ }
+@@ -321,23 +286,12 @@ gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
+ }
+ void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& cursor) {
+-  // Optimize the common case, where the cursor hasn't changed.
+-  // However, we can switch between different pixmaps, so only on the
+-  // non-pixmap branch.
+-  if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
+-      current_cursor_.GetCursorType() == cursor.GetCursorType()) {
+-    return;
+-  }
+-
+   current_cursor_ = cursor;
+   ShowCurrentCursor();
+ }
+ void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
+-  is_loading_ = is_loading;
+-  // Only call ShowCurrentCursor() when it will actually change the cursor.
+-  if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
+-    ShowCurrentCursor();
++
+ }
+ void RenderWidgetHostViewEfl::TextInputStateChanged(
+@@ -389,20 +343,7 @@ void RenderWidgetHostViewEfl::RenderViewGone(base::TerminationStatus status,
+ }
+ void RenderWidgetHostViewEfl::Destroy() {
+-  if (compositing_surface_ != gfx::kNullPluginWindow) {
+-  }
+-  if (do_x_grab_) {
+-    // Undo the X grab.
+-  }
+-
+-  if (preserve_window_->SmartObject()) {
+-    // If this is a popup or fullscreen widget, then we need to destroy the
+-    // window that we created to hold it.
+-    if (IsPopup() || is_fullscreen_) {
+-      ui::ActiveWindowWatcherX::RemoveObserver(this);
+-    }
+-    // See http://crbug.com/11847 for details.
+-  }
++  // FIXME: Check what should be deleted.
+   // The RenderWidgetHost's destruction led here, so don't call it.
+   host_ = NULL;
+@@ -410,7 +351,6 @@ void RenderWidgetHostViewEfl::Destroy() {
+ }
+ void RenderWidgetHostViewEfl::SetTooltipText(const string16& tooltip_text) {
+-  // I filed https://bugzilla.gnome.org/show_bug.cgi?id=604641 upstream.
+ }
+ void RenderWidgetHostViewEfl::SelectionChanged(const string16& text,
+@@ -445,10 +385,6 @@ void RenderWidgetHostViewEfl::SelectionBoundsChanged(
+ void RenderWidgetHostViewEfl::ScrollOffsetChanged() {
+ }
+-GdkEventButton* RenderWidgetHostViewEfl::GetLastMouseDown() {
+-  return 0;
+-}
+-
+ gfx::NativeView RenderWidgetHostViewEfl::BuildInputMethodsGtkMenu() {
+   return 0;
+ }
+@@ -464,10 +400,6 @@ bool RenderWidgetHostViewEfl::IsPopup() const {
+ void RenderWidgetHostViewEfl::DoSharedInit(Evas_Object* parent) {
+ }
+-void RenderWidgetHostViewEfl::DoPopupOrFullscreenInit(GtkWindow* window,
+-                                                      const gfx::Rect& bounds) {
+-}
+-
+ BackingStore* RenderWidgetHostViewEfl::AllocBackingStore(
+     const gfx::Size& /*size*/) {
+   return 0;  // We're using accelerated path.
+@@ -531,59 +463,6 @@ void RenderWidgetHostViewEfl::SetBackground(const SkBitmap& background) {
+   Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
+ }
+-void RenderWidgetHostViewEfl::ModifyEventForEdgeDragging(
+-    GtkWidget* widget, GdkEventMotion* event) {
+-  // If the widget is aligned with an edge of the monitor its on and the user
+-  // attempts to drag past that edge we track the number of times it has
+-  // occurred, so that we can force the widget to scroll when it otherwise
+-  // would be unable to, by modifying the (x,y) position in the drag
+-  // event that we forward on to webkit. If we get a move that's no longer a
+-  // drag or a drag indicating the user is no longer at that edge we stop
+-  // altering the drag events.
+-  int new_dragged_at_horizontal_edge = 0;
+-  int new_dragged_at_vertical_edge = 0;
+-  // Used for checking the edges of the monitor. We cache the values to save
+-  // roundtrips to the X server.
+-  CR_DEFINE_STATIC_LOCAL(gfx::Size, drag_monitor_size, ());
+-  if (event->state & GDK_BUTTON1_MASK) {
+-    if (drag_monitor_size.IsEmpty()) {
+-      // We can safely cache the monitor size for the duration of a drag.
+-      GdkScreen* screen = gtk_widget_get_screen(widget);
+-      int monitor =
+-          gdk_screen_get_monitor_at_point(screen, event->x_root, event->y_root);
+-      GdkRectangle geometry;
+-      gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
+-      drag_monitor_size.SetSize(geometry.width, geometry.height);
+-    }
+-    GtkAllocation allocation;
+-    gtk_widget_get_allocation(widget, &allocation);
+-    // Check X and Y independently, as the user could be dragging into a corner.
+-    if (event->x == 0 && event->x_root == 0) {
+-      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ - 1;
+-    } else if (allocation.width - 1 == static_cast<gint>(event->x) &&
+-        drag_monitor_size.width() - 1 == static_cast<gint>(event->x_root)) {
+-      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ + 1;
+-    }
+-
+-    if (event->y == 0 && event->y_root == 0) {
+-      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ - 1;
+-    } else if (allocation.height - 1 == static_cast<gint>(event->y) &&
+-        drag_monitor_size.height() - 1 == static_cast<gint>(event->y_root)) {
+-      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ + 1;
+-    }
+-
+-    event->x_root += new_dragged_at_horizontal_edge;
+-    event->x += new_dragged_at_horizontal_edge;
+-    event->y_root += new_dragged_at_vertical_edge;
+-    event->y += new_dragged_at_vertical_edge;
+-  } else {
+-    // Clear whenever we get a non-drag mouse move.
+-    drag_monitor_size.SetSize(0, 0);
+-  }
+-  dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge;
+-  dragged_at_vertical_edge_ = new_dragged_at_vertical_edge;
+-}
+-
+ void RenderWidgetHostViewEfl::Paint(const gfx::Rect& /*damage_rect*/) {
+   // If the GPU process is rendering directly into the View,
+   // call the compositor directly.
+@@ -609,7 +488,7 @@ void RenderWidgetHostViewEfl::GetScreenInfo(WebScreenInfo* results) {
+ }
+ gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
+-  return GetViewBounds();
++    return GetViewBounds();
+ }
+ gfx::GLSurfaceHandle RenderWidgetHostViewEfl::GetCompositingSurface() {
+@@ -759,11 +638,7 @@ void RenderWidgetHostViewEfl::FatalAccessibilityTreeError() {
+ }
+ void RenderWidgetHostViewEfl::OnAccessibilityNotifications(
+-    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
+-}
+-
+-AtkObject* RenderWidgetHostViewEfl::GetAccessible() {
+-  return 0;
++    const std::vector<AccessibilityHostMsg_NotificationParams>& /*params*/) {
+ }
+ void RenderWidgetHostViewEfl::OnCreatePluginContainer(
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.h b/content/browser/renderer_host/render_widget_host_view_efl.h
+index 2aba48f..617bce9 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.h
++++ b/content/browser/renderer_host/render_widget_host_view_efl.h
+@@ -6,7 +6,6 @@
+ #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
+ #include <Evas.h>
+-#include <gdk/gdk.h>
+ #include <string>
+ #include <vector>
+@@ -19,16 +18,13 @@
+ #include "ipc/ipc_sender.h"
+ #include "ui/base/animation/animation_delegate.h"
+ #include "ui/base/animation/slide_animation.h"
+-#include "ui/base/x/active_window_watcher_x_observer.h"
++//#include "ui/base/x/active_window_watcher_x_observer.h"
+ #include "ui/gfx/native_widget_types.h"
+ #include "ui/gfx/point.h"
+ #include "ui/gfx/preserve_window_delegate_efl.h"
+ #include "ui/gfx/rect.h"
+ #include "webkit/glue/webcursor.h"
+-#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
+-
+-typedef struct _GtkClipboard GtkClipboard;
+-typedef struct _GtkSelectionData GtkSelectionData;
++//#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
+ namespace gfx {
+ class PreserveWindow;
+@@ -46,7 +42,6 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+     : public gfx::PreserveWindowDelegate,
+       public RenderWidgetHostViewBase,
+       public BrowserAccessibilityDelegate,
+-      public ui::ActiveWindowWatcherXObserver,
+       public IPC::Sender {
+  public:
+   virtual ~RenderWidgetHostViewEfl();
+@@ -82,7 +77,6 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+   virtual void Hide() OVERRIDE;
+   virtual bool IsShowing() OVERRIDE;
+   virtual gfx::Rect GetViewBounds() const OVERRIDE;
+-  virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
+   virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
+   virtual void SetBackground(const SkBitmap& background) OVERRIDE;
+@@ -154,14 +148,9 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+       const std::vector<AccessibilityHostMsg_NotificationParams>& params)
+       OVERRIDE;
+-  // ActiveWindowWatcherXObserver implementation.
+-  virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
+-
+   // IPC::Sender implementation:
+   virtual bool Send(IPC::Message* message) OVERRIDE;
+-  void ModifyEventForEdgeDragging(GtkWidget* widget, GdkEventMotion* event);
+-
+   void ModifyEventMovementAndCoords(WebKit::WebMouseEvent* event);
+   void Paint(const gfx::Rect&);
+@@ -182,9 +171,6 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+   virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE;
+   virtual void FatalAccessibilityTreeError() OVERRIDE;
+-  // Get the root of the AtkObject* tree for accessibility.
+-  AtkObject* GetAccessible();
+-
+  protected:
+   friend class RenderWidgetHostView;
+@@ -203,10 +189,6 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+   // Do initialization needed by all InitAs*() methods.
+   void DoSharedInit(Evas_Object* parent);
+-  // Do initialization needed just by InitAsPopup() and InitAsFullscreen().
+-  // We move and resize |window| to |bounds| and show it and its contents.
+-  void DoPopupOrFullscreenInit(GtkWindow* window, const gfx::Rect& bounds);
+-
+   // Update the display cursor for the render view.
+   void ShowCurrentCursor();
+diff --git a/content/browser/renderer_host/window_utils_efl.cc b/content/browser/renderer_host/window_utils_efl.cc
+index 1c6c511..2834d59 100644
+--- a/content/browser/renderer_host/window_utils_efl.cc
++++ b/content/browser/renderer_host/window_utils_efl.cc
+@@ -16,8 +16,7 @@ namespace {
+ // Length of an inch in CSS's 1px unit.
+ const int kPixelsPerInch = 96;
+-int depthPerComponent(int depth)
+-{
++int depthPerComponent(int depth) {
+     switch (depth) {
+     case 0:
+     case 24:
+@@ -32,8 +31,7 @@ int depthPerComponent(int depth)
+ }
+-void GetScreenInfoEfl(WebKit::WebScreenInfo* results)
+-{
++void GetScreenInfoEfl(WebKit::WebScreenInfo* results) {
+   Ecore_X_Display* display = ecore_x_display_get();
+   Ecore_X_Screen* screen = ecore_x_default_screen_get();
+   int width, height;
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index 1e2edb8..ccdfbf3 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -4,10 +4,6 @@
+ #include "content/browser/web_contents/web_contents_view_efl.h"
+-#include <gdk/gdk.h>
+-#include <gdk/gdkkeysyms.h>
+-#include <gtk/gtk.h>
+-
+ #include <algorithm>
+ #include "base/string_util.h"
+@@ -15,14 +11,11 @@
+ #include "build/build_config.h"
+ #include "content/browser/renderer_host/render_view_host_factory.h"
+ #include "content/browser/renderer_host/render_view_host_impl.h"
+-#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
++#include "content/browser/renderer_host/render_widget_host_view_efl.h"
+ #include "content/browser/web_contents/interstitial_page_impl.h"
+ #include "content/browser/web_contents/web_contents_impl.h"
+-#include "content/browser/web_contents/web_drag_dest_gtk.h"
+-#include "content/browser/web_contents/web_drag_source_gtk.h"
+ #include "content/public/browser/web_contents_delegate.h"
+ #include "content/public/browser/web_contents_view_delegate.h"
+-#include "ui/base/gtk/gtk_expanded_container.h"
+ #include "ui/gfx/image/image_skia.h"
+ #include "ui/gfx/point.h"
+ #include "ui/gfx/rect.h"
+@@ -33,48 +26,6 @@ using WebKit::WebDragOperation;
+ using WebKit::WebDragOperationsMask;
+ namespace content {
+-namespace {
+-
+-// Called when the mouse leaves the widget. We notify our delegate.
+-gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
+-                       WebContentsImpl* web_contents) {
+-  if (web_contents->GetDelegate())
+-    web_contents->GetDelegate()->ContentsMouseEvent(
+-        web_contents, gfx::Point(event->x_root, event->y_root), false);
+-  return FALSE;
+-}
+-
+-// Called when the mouse moves within the widget. We notify our delegate.
+-gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
+-                     WebContentsImpl* web_contents) {
+-  if (web_contents->GetDelegate())
+-    web_contents->GetDelegate()->ContentsMouseEvent(
+-        web_contents, gfx::Point(event->x_root, event->y_root), true);
+-  return FALSE;
+-}
+-
+-// See tab_contents_view_views.cc for discussion of mouse scroll zooming.
+-gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
+-                       WebContentsImpl* web_contents) {
+-  if ((event->state & gtk_accelerator_get_default_mod_mask()) !=
+-      GDK_CONTROL_MASK) {
+-    return FALSE;
+-  }
+-
+-  WebContentsDelegate* delegate = web_contents->GetDelegate();
+-  if (!delegate)
+-    return FALSE;
+-
+-  if (!(event->direction == GDK_SCROLL_DOWN ||
+-        event->direction == GDK_SCROLL_UP)) {
+-    return FALSE;
+-  }
+-
+-  delegate->ContentsZoomChange(event->direction == GDK_SCROLL_UP);
+-  return TRUE;
+-}
+-
+-}  // namespace
+ WebContentsViewPort* CreateWebContentsView(
+     WebContentsImpl* web_contents,
+@@ -119,11 +70,7 @@ void WebContentsViewEfl::OnTabCrashed(base::TerminationStatus status,
+ }
+ void WebContentsViewEfl::Focus() {
+-  if (web_contents_->ShowingInterstitialPage()) {
+-    web_contents_->GetInterstitialPage()->Focus();
+-  } else if (delegate_) {
+-    delegate_->Focus();
+-  }
++  // TODO: Focus.
+ }
+ void WebContentsViewEfl::SetInitialFocus() {
+@@ -146,14 +93,6 @@ WebDropData* WebContentsViewEfl::GetDropData() const {
+ gfx::Rect WebContentsViewEfl::GetViewBounds() const {
+   gfx::Rect rect;
+-  GdkWindow* window = gtk_widget_get_window(GetNativeView());
+-  if (!window) {
+-    rect.SetRect(0, 0, requested_size_.width(), requested_size_.height());
+-    return rect;
+-  }
+-  int x = 0, y = 0, w, h;
+-  gdk_window_get_geometry(window, &x, &y, &w, &h, NULL);
+-  rect.SetRect(x, y, w, h);
+   return rect;
+ }
+@@ -219,13 +158,7 @@ void WebContentsViewEfl::GotFocus() {
+ // This is called when the renderer asks us to take focus back (i.e., it has
+ // iterated past the last focusable element on the page).
+ void WebContentsViewEfl::TakeFocus(bool reverse) {
+-  if (!web_contents_->GetDelegate())
+-    return;
+-  if (!web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
+-      GetTopLevelNativeWindow()) {
+-    gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()),
+-        reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
+-  }
++  /* TODO: Assign Focus to EFL evas_object */
+ }
+ void WebContentsViewEfl::UpdateDragDest(RenderViewHost* host) {
+diff --git a/content/content_browser.gypi b/content/content_browser.gypi
+index 3d881a2..1484aaa 100644
+--- a/content/content_browser.gypi
++++ b/content/content_browser.gypi
+@@ -758,6 +758,7 @@
+     'browser/renderer_host/native_web_keyboard_event_android.cc',
+     'browser/renderer_host/native_web_keyboard_event_aura.cc',
+     'browser/renderer_host/native_web_keyboard_event.cc',
++    'browser/renderer_host/native_web_keyboard_event_efl.cc',
+     'browser/renderer_host/native_web_keyboard_event_gtk.cc',
+     'browser/renderer_host/native_web_keyboard_event_mac.mm',
+     'browser/renderer_host/native_web_keyboard_event_win.cc',
+@@ -1172,6 +1173,7 @@
+     ['toolkit_uses_efl == 1', {
+       'dependencies': [
+         '../build/linux/system.gyp:efl',
++        '../dbus/dbus.gyp:dbus',
+       ],
+       'sources/': [
+         ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
+diff --git a/content/shell/shell.h b/content/shell/shell.h
+index 0d772eb..e58bb42 100644
+--- a/content/shell/shell.h
++++ b/content/shell/shell.h
+@@ -233,10 +233,6 @@ class Shell : public WebContentsDelegate,
+   WNDPROC default_edit_wnd_proc_;
+   static HINSTANCE instance_handle_;
+ #elif defined(TOOLKIT_EFL)
+-  // TODO(rakuco): Once gfx::NativeWindow is set to Evas_Object*, we
+-  // can just use window_.
+-  Evas_Object* main_window_;
+-
+   int content_width_;
+   int content_height_;
+ #elif defined(TOOLKIT_GTK)
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+index 3078d63..557424e 100644
+--- a/content/shell/shell_efl.cc
++++ b/content/shell/shell_efl.cc
+@@ -52,22 +52,22 @@ void Shell::PlatformCreateWindow(int width, int height) {
+   if (headless_)
+     return;
+-  main_window_ = elm_win_util_standard_add("Content Shell", "Content Shell");
+-  elm_win_autodel_set(main_window_, true);
+-  evas_object_resize(main_window_, width, height);
+-  evas_object_event_callback_add(main_window_, EVAS_CALLBACK_DEL,
++  window_ = elm_win_util_standard_add("Content Shell", "Content Shell");
++  elm_win_autodel_set(window_, true);
++  evas_object_resize(window_, width, height);
++  evas_object_event_callback_add(window_, EVAS_CALLBACK_DEL,
+                                  OnMainWindowDel, this);
+-  evas_object_show(main_window_);
++  evas_object_show(window_);
+ }
+ void Shell::PlatformSetContents() {
+   if (headless_)
+     return;
+-  Evas_Object* view_box = elm_box_add(main_window_);
++  Evas_Object* view_box = elm_box_add(window_);
+   evas_object_size_hint_weight_set(view_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_win_resize_object_add(main_window_, view_box);
++  elm_win_resize_object_add(window_, view_box);
+   WebContentsView* content_view = web_contents_->GetView();
+   static_cast<WebContentsViewEfl*>(content_view)->SetViewContainerBox(view_box);
+@@ -76,6 +76,8 @@ void Shell::PlatformSetContents() {
+ void Shell::SizeTo(int width, int height) {
+   content_width_ = width;
+   content_height_ = height;
++  if (web_contents_) {
++  }
+ }
+ void Shell::PlatformResizeSubViews() {
+@@ -94,7 +96,7 @@ void Shell::PlatformSetTitle(const string16& title) {
+     return;
+   std::string title_utf8 = UTF16ToUTF8(title);
+-  elm_win_title_set(main_window_, title_utf8.c_str());
++  elm_win_title_set(window_, title_utf8.c_str());
+ }
+ void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
+diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
+index db6a785..283f37f 100644
+--- a/content/shell/shell_web_contents_view_delegate.h
++++ b/content/shell/shell_web_contents_view_delegate.h
+@@ -53,7 +53,7 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+   WebContents* web_contents_;
+   ContextMenuParams params_;
+-#if defined(TOOLKIT_GTK) && !defined(TOOLKIT_EFL)
++#if defined(TOOLKIT_GTK)
+   ui::OwnedWidgetGtk floating_;
+   GtkWidget* expanded_container_;
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+index 9e10940..18498f3 100644
+--- a/content/shell/shell_web_contents_view_delegate_efl.cc
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -19,8 +19,6 @@
+ #include "content/shell/shell_switches.h"
+ #include "content/shell/shell_web_contents_view_delegate_creator.h"
+ #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
+-#include "ui/base/gtk/focus_store_gtk.h"
+-#include "ui/base/gtk/gtk_floating_container.h"
+ using WebKit::WebContextMenuData;
+@@ -50,22 +48,4 @@ WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
+   return NULL;
+ }
+-void ShellWebContentsViewDelegate::Initialize(GtkWidget* expanded_container,
+-                                              ui::FocusStoreGtk* focus_store) {
+-}
+-
+-gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const {
+-  return 0;
+-}
+-
+-void ShellWebContentsViewDelegate::Focus() {
+-}
+-
+-gboolean ShellWebContentsViewDelegate::OnNativeViewFocusEvent(
+-    GtkWidget* widget,
+-    GtkDirectionType type,
+-    gboolean* return_value) {
+-  return false;
+-}
+-
+ }  // namespace content
+diff --git a/printing/printing.gyp b/printing/printing.gyp
+index be4d883..4dccbd2 100644
+--- a/printing/printing.gyp
++++ b/printing/printing.gyp
+@@ -207,6 +207,11 @@
+             'printing_context_gtk.h',
+           ],
+         }],
++        ['toolkit_uses_efl==1 and chromeos==0', {
++          'sources': [
++            'printing_context_efl.cc',
++          ],
++        }],
+       ],
+     },
+     {
+diff --git a/printing/printing_context_efl.cc b/printing/printing_context_efl.cc
+new file mode 100644
+index 0000000..ec2b364
+--- /dev/null
++++ b/printing/printing_context_efl.cc
+@@ -0,0 +1,20 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "base/logging.h"
++#include "base/values.h"
++#include "printing/metafile.h"
++#include "printing/print_dialog_gtk_interface.h"
++#include "printing/print_job_constants.h"
++#include "printing/units.h"
++
++namespace printing {
++
++// static
++PrintingContext* PrintingContext::Create(const std::string& app_locale) {
++  return 0;
++}
++
++}  // namespace printing
++
+diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h
+index ae6d708..29dd5b8 100644
+--- a/ui/base/clipboard/clipboard.h
++++ b/ui/base/clipboard/clipboard.h
+@@ -113,6 +113,7 @@ class UI_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) {
+     explicit FormatType(const GdkAtom& native_format);
+     const GdkAtom& ToGdkAtom() const { return data_; }
+     GdkAtom data_;
++#elif defined(TOOLKIT_EFL) // Mikhail FIXME: Implementation is required.
+ #elif defined(OS_ANDROID)
+     explicit FormatType(const std::string& native_format);
+     const std::string& data() const { return data_; }
+diff --git a/ui/base/clipboard/clipboard_efl.cc b/ui/base/clipboard/clipboard_efl.cc
+new file mode 100644
+index 0000000..25a2e7c
+--- /dev/null
++++ b/ui/base/clipboard/clipboard_efl.cc
+@@ -0,0 +1,219 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/base/clipboard/clipboard.h"
++
++#include <X11/extensions/Xfixes.h>
++#include <X11/Xatom.h>
++#include <map>
++#include <set>
++#include <string>
++#include <utility>
++
++#include "base/basictypes.h"
++#include "base/files/file_path.h"
++#include "base/logging.h"
++#include "base/memory/singleton.h"
++#include "base/utf_string_conversions.h"
++#include "third_party/skia/include/core/SkBitmap.h"
++#include "ui/base/clipboard/custom_data_helper.h"
++#include "ui/base/x/x11_util.h"
++#include "ui/gfx/canvas.h"
++#include "ui/gfx/size.h"
++
++namespace ui {
++
++namespace {
++
++const char kSourceTagType[] = "org.chromium.source-tag";
++const char kMimeTypeBitmap[] = "image/bmp";
++const char kMimeTypeMozillaURL[] = "text/x-moz-url";
++const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
++const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
++
++}  // namespace
++Clipboard::FormatType::FormatType() {
++}
++
++Clipboard::FormatType::~FormatType() {
++}
++
++std::string Clipboard::FormatType::Serialize() const {
++  return "";
++}
++
++Clipboard::FormatType Clipboard::FormatType::Deserialize(
++    const std::string&) {
++  static FormatType type;
++  return type;
++}
++
++Clipboard::Clipboard() {
++}
++
++Clipboard::~Clipboard() {
++
++}
++
++void Clipboard::WriteObjectsImpl(Buffer buffer,
++                                 const ObjectMap& objects,
++                                 SourceTag tag) {
++}
++
++void Clipboard::WriteText(const char* text_data, size_t text_len) {
++}
++
++void Clipboard::WriteHTML(const char* markup_data,
++                          size_t markup_len,
++                          const char* url_data,
++                          size_t url_len) {
++}
++
++void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) {
++}
++
++// Write an extra flavor that signifies WebKit was the last to modify the
++// pasteboard. This flavor has no data.
++void Clipboard::WriteWebSmartPaste() {
++}
++
++void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) {
++}
++
++void Clipboard::WriteBookmark(const char* title_data, size_t title_len,
++                              const char* url_data, size_t url_len) {
++}
++
++void Clipboard::WriteData(const FormatType& format,
++                          const char* data_data,
++                          size_t data_len) {
++}
++
++void Clipboard::WriteSourceTag(SourceTag tag) {
++}
++
++// We do not use gtk_clipboard_wait_is_target_available because of
++// a bug with the gtk clipboard. It caches the available targets
++// and does not always refresh the cache when it is appropriate.
++bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format,
++                                  Clipboard::Buffer buffer) const {
++  return false;
++}
++
++void Clipboard::Clear(Clipboard::Buffer buffer) {
++}
++
++void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
++                                   std::vector<string16>* types,
++                                   bool* contains_filenames) const {
++}
++
++
++void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const {
++}
++
++void Clipboard::ReadAsciiText(Clipboard::Buffer buffer,
++                              std::string* result) const {
++}
++
++// TODO(estade): handle different charsets.
++// TODO(port): set *src_url.
++void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup,
++                         std::string* src_url, uint32* fragment_start,
++                         uint32* fragment_end) const {
++}
++
++void Clipboard::ReadRTF(Buffer buffer, std::string* result) const {
++}
++
++SkBitmap Clipboard::ReadImage(Buffer buffer) const {
++    return SkBitmap();
++}
++
++void Clipboard::ReadCustomData(Buffer buffer,
++                               const string16& type,
++                               string16* result) const {
++}
++
++void Clipboard::ReadBookmark(string16* title, std::string* url) const {
++  // TODO(estade): implement this.
++  NOTIMPLEMENTED();
++}
++
++void Clipboard::ReadData(const FormatType& format, std::string* result) const {
++}
++
++SourceTag Clipboard::ReadSourceTag(Buffer buffer) const {
++  std::string result;
++  return Binary2SourceTag(result);
++}
++
++uint64 Clipboard::GetSequenceNumber(Buffer buffer) {
++  return 0;
++}
++
++//static
++Clipboard::FormatType Clipboard::GetFormatType(
++    const std::string& format_string) {
++  static FormatType type;
++  return type;
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
++  static FormatType type;
++  return type;
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
++  return GetPlainTextFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetUrlFormatType() {
++  return GetPlainTextFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetUrlWFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++// static
++const Clipboard::FormatType& Clipboard::GetSourceTagFormatType() {
++  return GetPlainTextWFormatType();
++}
++
++}  // namespace ui
+diff --git a/ui/base/resource/resource_bundle_efl.cc b/ui/base/resource/resource_bundle_efl.cc
+new file mode 100644
+index 0000000..915cf93
+--- /dev/null
++++ b/ui/base/resource/resource_bundle_efl.cc
+@@ -0,0 +1,64 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/base/resource/resource_bundle.h"
++
++#include "base/i18n/rtl.h"
++#include "base/logging.h"
++#include "base/memory/ref_counted_memory.h"
++#include "base/path_service.h"
++#include "base/synchronization/lock.h"
++#include "third_party/skia/include/core/SkBitmap.h"
++#include "ui/base/layout.h"
++#include "ui/base/resource/resource_handle.h"
++#include "ui/base/ui_base_paths.h"
++
++namespace ui {
++
++namespace {
++
++base::FilePath GetResourcesPakFilePath(const std::string& pak_name) {
++  base::FilePath path;
++  if (PathService::Get(base::DIR_MODULE, &path))
++    return path.AppendASCII(pak_name.c_str());
++
++  // Return just the name of the pack file.
++  return base::FilePath(pak_name.c_str());
++}
++
++}  // namespace
++
++void ResourceBundle::LoadCommonResources() {
++  AddDataPackFromPath(GetResourcesPakFilePath("chrome.pak"),
++                      SCALE_FACTOR_NONE);
++  AddDataPackFromPath(GetResourcesPakFilePath(
++                      "chrome_100_percent.pak"),
++                      SCALE_FACTOR_100P);
++}
++
++gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id, ImageRTL rtl) {
++  // Use the negative |resource_id| for the key for BIDI-aware images.
++  int key = rtl == RTL_ENABLED ? -resource_id : resource_id;
++
++  // Check to see if the image is already in the cache.
++  {
++    base::AutoLock lock_scope(*images_and_fonts_lock_);
++    if (images_.count(key))
++      return images_[key];
++  }
++
++  gfx::Image image;
++  if (delegate_)
++    image = delegate_->GetNativeImageNamed(resource_id, rtl);
++  base::AutoLock lock_scope(*images_and_fonts_lock_);
++
++  // Another thread raced the load and has already cached the image.
++  if (images_.count(key))
++    return images_[key];
++
++  images_[key] = image;
++  return images_[key];
++}
++
++}  // namespace ui
+diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
+index 720e347..8916610 100644
+--- a/ui/gfx/native_widget_types.h
++++ b/ui/gfx/native_widget_types.h
+@@ -106,6 +106,8 @@ typedef struct _GdkPixbuf GdkPixbuf;
+ typedef struct _GdkRegion GdkRegion;
+ typedef struct _GtkWidget GtkWidget;
+ typedef struct _GtkWindow GtkWindow;
++#elif defined(TOOLKIT_EFL)
++typedef struct _Evas_Object Evas_Object;
+ #elif defined(OS_ANDROID)
+ struct ANativeWindow;
+ namespace ui {
+@@ -145,6 +147,12 @@ typedef GtkWidget* NativeView;
+ typedef GtkWindow* NativeWindow;
+ typedef GdkRegion* NativeRegion;
+ typedef GdkEvent* NativeEvent;
++#elif defined(TOOLKIT_EFL) // FIXME: Check the types here.
++typedef void* NativeCursor;
++typedef Evas_Object* NativeView;
++typedef void* NativeRegion;
++typedef Evas_Object* NativeWindow;
++typedef void* NativeEvent;
+ #elif defined(OS_ANDROID)
+ typedef void* NativeCursor;
+ typedef ui::ViewAndroid* NativeView;
+@@ -172,6 +180,11 @@ typedef PangoFontDescription* NativeFont;
+ typedef GtkWidget* NativeEditView;
+ typedef cairo_t* NativeDrawingContext;
+ typedef void* NativeViewAccessible;
++#elif defined(TOOLKIT_EFL)
++typedef PangoFontDescription* NativeFont;
++typedef Evas_Object* NativeEditView;
++typedef cairo_t* NativeDrawingContext;
++typedef void* NativeViewAccessible;
+ #elif defined(USE_AURA)
+ typedef PangoFontDescription* NativeFont;
+ typedef void* NativeEditView;
+diff --git a/ui/native_theme/native_theme.gyp b/ui/native_theme/native_theme.gyp
+index 70d27a3..df3e183 100644
+--- a/ui/native_theme/native_theme.gyp
++++ b/ui/native_theme/native_theme.gyp
+@@ -31,6 +31,7 @@
+         'native_theme_aura.h',
+         'native_theme_base.cc',
+         'native_theme_base.h',
++        'native_theme_efl.cc',
+         'native_theme_gtk.cc',
+         'native_theme_gtk.h',
+         'native_theme_mac.h',
+diff --git a/ui/native_theme/native_theme_efl.cc b/ui/native_theme/native_theme_efl.cc
+new file mode 100644
+index 0000000..ba884d6
+--- /dev/null
++++ b/ui/native_theme/native_theme_efl.cc
+@@ -0,0 +1,101 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "base/basictypes.h"
++#include "base/logging.h"
++
++#include "ui/native_theme/native_theme.h"
++#include "ui/native_theme/native_theme_base.h"
++
++
++namespace {
++
++const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128);
++
++// Theme colors returned by GetSystemColor().
++
++// FocusableBorder:
++const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE);
++const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9);
++
++// MenuItem
++const SkColor kFocusedMenuItemBackgroundColor = SkColorSetARGB(13, 0, 0, 0);
++const SkColor kHoverMenuItemBackgroundColor = SkColorSetRGB(204, 204, 204);
++
++// MenuButton
++const SkColor kEnabledMenuButtonBorderColor = SkColorSetARGB(36, 0, 0, 0);
++const SkColor kFocusedMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0);
++const SkColor kHoverMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0);
++
++// TextButton:
++const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xde, 0xde, 0xde);
++const SkColor kTextButtonEnabledColor = SkColorSetRGB(6, 45, 117);
++const SkColor kTextButtonDisabledColor = SkColorSetRGB(161, 161, 146);
++const SkColor kTextButtonHighlightColor = SkColorSetARGB(200, 255, 255, 255);
++const SkColor kTextButtonHoverColor = kTextButtonEnabledColor;
++
++}  // namespace
++
++namespace ui {
++
++// EFL implementation of native theme support.
++class NativeThemeEfl : public NativeThemeBase {
++ public:
++  NativeThemeEfl() { }
++  virtual SkColor GetSystemColor(ColorId /*color_id*/) const OVERRIDE;
++
++ private:
++  virtual ~NativeThemeEfl() { }
++
++  DISALLOW_COPY_AND_ASSIGN(NativeThemeEfl);
++};
++
++SkColor NativeThemeEfl::GetSystemColor(ColorId color_id) const {
++  switch (color_id) {
++    case kColorId_DialogBackground:
++      return SkColorSetRGB(0xFF, 0xFF, 0xFF);
++    // FocusableBorder:
++    case kColorId_FocusedBorderColor:
++      return kFocusedBorderColor;
++    case kColorId_UnfocusedBorderColor:
++      return kUnfocusedBorderColor;
++
++    // MenuItem
++    case kColorId_FocusedMenuItemBackgroundColor:
++      return kFocusedMenuItemBackgroundColor;
++    case kColorId_HoverMenuItemBackgroundColor:
++      return kHoverMenuItemBackgroundColor;
++    case kColorId_EnabledMenuButtonBorderColor:
++      return kEnabledMenuButtonBorderColor;
++    case kColorId_FocusedMenuButtonBorderColor:
++      return kFocusedMenuButtonBorderColor;
++    case kColorId_HoverMenuButtonBorderColor:
++      return kHoverMenuButtonBorderColor;
++
++    // TextButton:
++    case kColorId_TextButtonBackgroundColor:
++      return kTextButtonBackgroundColor;
++    case kColorId_TextButtonEnabledColor:
++      return kTextButtonEnabledColor;
++    case kColorId_TextButtonDisabledColor:
++      return kTextButtonDisabledColor;
++    case kColorId_TextButtonHighlightColor:
++      return kTextButtonHighlightColor;
++    case kColorId_TextButtonHoverColor:
++      return kTextButtonHoverColor;
++
++    default:
++      NOTREACHED() << "Invalid color_id: " << color_id;
++      break;
++  }
++  return kInvalidColorIdColor;
++}
++
++// static
++NativeTheme* NativeTheme::instance() {
++  static NativeTheme* theme = new NativeThemeEfl();
++  return theme;
++}
++
++}  // namespace ui
+diff --git a/ui/snapshot/snapshot.gyp b/ui/snapshot/snapshot.gyp
+index cf93fa9..5b41f96 100644
+--- a/ui/snapshot/snapshot.gyp
++++ b/ui/snapshot/snapshot.gyp
+@@ -22,6 +22,7 @@
+         'snapshot.h',
+         'snapshot_android.cc',
+         'snapshot_aura.cc',
++        'snapshot_efl.cc',
+         'snapshot_export.h',
+         'snapshot_gtk.cc',
+         'snapshot_ios.mm',
+diff --git a/ui/snapshot/snapshot_efl.cc b/ui/snapshot/snapshot_efl.cc
+new file mode 100644
+index 0000000..d1db897
+--- /dev/null
++++ b/ui/snapshot/snapshot_efl.cc
+@@ -0,0 +1,27 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "ui/snapshot/snapshot.h"
++
++#include "base/logging.h"
++#include "ui/base/x/x11_util.h"
++#include "ui/gfx/rect.h"
++
++namespace ui {
++
++bool GrabViewSnapshot(gfx::NativeView view,
++                      std::vector<unsigned char>* png_representation,
++                      const gfx::Rect& snapshot_bounds) {
++  // TODO implement EFL snapshot
++  return true;
++}
++
++bool GrabWindowSnapshot(gfx::NativeWindow window,
++                        std::vector<unsigned char>* png_representation,
++                        const gfx::Rect& snapshot_bounds) {
++  // TODO implement EFL snapshot
++  return true;
++}
++
++}  // namespace ui
+diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h
+index 535567a..391dbc9 100644
+--- a/ui/surface/transport_dib.h
++++ b/ui/surface/transport_dib.h
+@@ -14,7 +14,7 @@
+ #if defined(OS_WIN)
+ #include <windows.h>
+-#elif defined(TOOLKIT_GTK) || \
++#elif defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || \
+   (defined(OS_LINUX) && defined(USE_AURA) && defined(USE_X11))
+ #include "ui/base/x/x11_util.h"
+ #endif
+@@ -81,7 +81,7 @@ class SURFACE_EXPORT TransportDIB {
+     static int fake_handle = 10;
+     return reinterpret_cast<Handle>(fake_handle++);
+   }
+-#elif defined(TOOLKIT_GTK) || \
++#elif defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || \
+   (defined(OS_LINUX) && defined(USE_AURA) && defined(USE_X11))
+   typedef int Handle;  // These two ints are SysV IPC shared memory keys
+   struct Id {
+@@ -188,7 +188,7 @@ class SURFACE_EXPORT TransportDIB {
+   // wire to give this transport DIB to another process.
+   Handle handle() const;
+-#if defined(TOOLKIT_GTK) || \
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || \
+   (defined(OS_LINUX) && defined(USE_AURA) && defined(USE_X11))
+   // Map the shared memory into the X server and return an id for the shared
+   // segment.
+@@ -210,7 +210,7 @@ class SURFACE_EXPORT TransportDIB {
+   // Verifies that the dib can hold a canvas of the requested dimensions.
+   bool VerifyCanvasSize(int w, int h);
+-#if defined(TOOLKIT_GTK) || \
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || \
+   (defined(OS_LINUX) && defined(USE_AURA) && defined(USE_X11))
+   Id key_;  // SysV shared memory id
+   void* address_;  // mapped address
+diff --git a/ui/surface/transport_dib_posix.cc b/ui/surface/transport_dib_posix.cc
+index fcb935d..4f10f97 100644
+--- a/ui/surface/transport_dib_posix.cc
++++ b/ui/surface/transport_dib_posix.cc
+@@ -6,7 +6,7 @@
+ // Desktop GTK Linux builds use the old-style SYSV SHM based DIBs.
+ // Linux Aura and Chrome OS do too. This will change very soon.
+-#if !defined(TOOLKIT_GTK) && !(defined(OS_LINUX) && defined(USE_AURA))
++#if !defined(TOOLKIT_GTK) && !defined(TOOLKIT_EFL) && !(defined(OS_LINUX) && defined(USE_AURA))
+ #include <sys/stat.h>
+ #include <unistd.h>
+diff --git a/ui/surface/transport_dib_sysvipc.cc b/ui/surface/transport_dib_sysvipc.cc
+index a15ca41..3c516a7 100644
+--- a/ui/surface/transport_dib_sysvipc.cc
++++ b/ui/surface/transport_dib_sysvipc.cc
+@@ -6,7 +6,7 @@
+ // Desktop GTK Linux builds use the old-style SYSV SHM based DIBs.
+ // Linux Aura and Chrome OS do too. This will change very soon.
+-#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && defined(USE_AURA))
++#if defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL) || (defined(OS_LINUX) && defined(USE_AURA))
+ #include <errno.h>
+ #include <stdlib.h>
+diff --git a/ui/ui.gyp b/ui/ui.gyp
+index a7c9cbf..e6c240e 100644
+--- a/ui/ui.gyp
++++ b/ui/ui.gyp
+@@ -707,9 +707,20 @@
+             'gfx/efl_util.h',
+             'gfx/screen_efl.cc',
+           ],
+-          'sources!': [
+-            'gfx/screen_gtk.cc',
+-          ],
++          'sources/': [
++            ['exclude', 'gfx/gtk_'],
++            ['exclude', 'gfx/gtk_util.cc'],
++            ['exclude', 'gfx/gtk_util.h'],
++            ['exclude', 'gfx/screen_gtk.cc'],
++            ['exclude', 'base/work_area_watcher_observer.h'],
++            ['exclude', 'base/x/active_window_watcher_x.cc'],
++            ['exclude', 'base/x/active_window_watcher_x.h'],
++            ['exclude', 'base/x/active_window_watcher_x_observer.h'],
++            ['exclude', 'base/x/root_window_property_watcher_x.cc'],
++            ['exclude', 'base/x/root_window_property_watcher_x.h'],
++            ['exclude', 'base/x/work_area_watcher_x.cc'],
++            ['exclude', 'base/x/work_area_watcher_x.h'],
++           ],
+         }],
+         ['chromeos==1 or (use_aura==1 and OS=="linux" and use_x11==0)', {
+           'sources!': [
+diff --git a/webkit/glue/webcursor_efl.cc b/webkit/glue/webcursor_efl.cc
+new file mode 100644
+index 0000000..7fcbcd2
+--- /dev/null
++++ b/webkit/glue/webcursor_efl.cc
+@@ -0,0 +1,35 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "webkit/glue/webcursor.h"
++
++#include "base/logging.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
++
++using WebKit::WebCursorInfo;
++
++gfx::NativeCursor WebCursor::GetNativeCursor() {
++  return 0;
++}
++
++void WebCursor::InitPlatformData() {
++}
++
++bool WebCursor::SerializePlatformData(Pickle* pickle) const {
++  return true;
++}
++
++bool WebCursor::DeserializePlatformData(PickleIterator* iter) {
++  return true;
++}
++
++bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
++  return true;
++}
++
++void WebCursor::CleanupPlatformData() {
++}
++
++void WebCursor::CopyPlatformData(const WebCursor& other) {
++}
+diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
+index 93ec07c..f9d0f4a 100644
+--- a/webkit/glue/webkit_glue.gypi
++++ b/webkit/glue/webkit_glue.gypi
+@@ -153,6 +153,7 @@
+         '../plugins/npapi/webplugin_delegate_impl.h',
+         '../plugins/npapi/webplugin_delegate_impl_android.cc',
+         '../plugins/npapi/webplugin_delegate_impl_aura.cc',
++        '../plugins/npapi/webplugin_delegate_impl_efl.cc',
+         '../plugins/npapi/webplugin_delegate_impl_gtk.cc',
+         '../plugins/npapi/webplugin_delegate_impl_mac.mm',
+         '../plugins/npapi/webplugin_delegate_impl_win.cc',
+@@ -313,6 +314,7 @@
+         'webcursor_aura.cc',
+         'webcursor_aurawin.cc',
+         'webcursor_aurax11.cc',
++        'webcursor_efl.cc',
+         'webcursor_null.cc',
+         'webcursor_gtk.cc',
+         'webcursor_gtk_data.h',
+diff --git a/webkit/plugins/npapi/webplugin_delegate_impl_efl.cc b/webkit/plugins/npapi/webplugin_delegate_impl_efl.cc
+new file mode 100644
+index 0000000..1349abc
+--- /dev/null
++++ b/webkit/plugins/npapi/webplugin_delegate_impl_efl.cc
+@@ -0,0 +1,85 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
++
++#include <string>
++#include <vector>
++
++#include "base/metrics/stats_counters.h"
++#include "skia/ext/platform_canvas.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
++#include "ui/gfx/blit.h"
++#include "webkit/plugins/npapi/plugin_instance.h"
++#include "webkit/plugins/npapi/webplugin.h"
++#include "webkit/plugins/plugin_constants.h"
++
++#include "third_party/npapi/bindings/npapi_x11.h"
++
++using WebKit::WebCursorInfo;
++using WebKit::WebKeyboardEvent;
++using WebKit::WebInputEvent;
++using WebKit::WebMouseEvent;
++
++namespace webkit {
++namespace npapi {
++
++WebPluginDelegateImpl::WebPluginDelegateImpl(
++    PluginInstance* instance) {
++}
++
++WebPluginDelegateImpl::~WebPluginDelegateImpl() {
++}
++
++bool WebPluginDelegateImpl::PlatformInitialize() {
++  return true;
++}
++
++void WebPluginDelegateImpl::PlatformDestroyInstance() {
++  // Nothing to do here.
++}
++
++void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas,
++                                  const gfx::Rect& rect) {
++}
++
++bool WebPluginDelegateImpl::WindowedCreatePlugin() {
++  return true;
++}
++
++void WebPluginDelegateImpl::WindowedDestroyWindow() {
++}
++
++bool WebPluginDelegateImpl::WindowedReposition(
++    const gfx::Rect& window_rect,
++    const gfx::Rect& clip_rect) {
++  return true;
++}
++
++void WebPluginDelegateImpl::WindowedSetWindow() {
++}
++
++void WebPluginDelegateImpl::WindowlessUpdateGeometry(
++    const gfx::Rect& window_rect,
++    const gfx::Rect& clip_rect) {
++}
++
++void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context,
++                                            const gfx::Rect& damage_rect) {
++}
++
++void WebPluginDelegateImpl::WindowlessSetWindow() {
++}
++
++bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
++  return true;
++}
++
++bool WebPluginDelegateImpl::PlatformHandleInputEvent(
++    const WebInputEvent& event, WebCursorInfo* cursor_info) {
++  return true;
++}
++
++}  // namespace npapi
++}  // namespace webkit
+-- 
+1.8.1.2
+
diff --git a/patchset/0004-Event-handling-implementation.patch b/patchset/0004-Event-handling-implementation.patch
new file mode 100644 (file)
index 0000000..3d9bab1
--- /dev/null
@@ -0,0 +1,780 @@
+From 6990ea4b3501a7eece77a7593a9fda512ad5aa25 Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Fri, 28 Jun 2013 09:57:28 +0300
+Subject: [PATCH 04/33] Event handling implementation
+
+Keyboard + Mouse events are handled
+Fix unicode and raw key events handling
+---
+ .../renderer_host/native_web_keyboard_event_efl.cc |  19 +-
+ .../renderer_host/render_widget_host_view_efl.cc   |  33 +-
+ .../renderer_host/render_widget_host_view_efl.h    |  14 +-
+ .../renderer_host/web_input_event_factory_efl.cc   | 417 +++++++++++++++++++++
+ .../renderer_host/web_input_event_factory_efl.h    |  32 ++
+ content/content_browser.gypi                       |   7 +-
+ ui/gfx/efl_event.h                                 |  33 ++
+ ui/gfx/native_widget_types.h                       |   5 +-
+ ui/gfx/preserve_window_delegate_efl.h              |  12 +-
+ ui/ui.gyp                                          |   1 +
+ 10 files changed, 538 insertions(+), 35 deletions(-)
+ create mode 100644 content/browser/renderer_host/web_input_event_factory_efl.cc
+ create mode 100644 content/browser/renderer_host/web_input_event_factory_efl.h
+ create mode 100644 ui/gfx/efl_event.h
+
+diff --git a/content/browser/renderer_host/native_web_keyboard_event_efl.cc b/content/browser/renderer_host/native_web_keyboard_event_efl.cc
+index 78b258a..23ae9c2 100644
+--- a/content/browser/renderer_host/native_web_keyboard_event_efl.cc
++++ b/content/browser/renderer_host/native_web_keyboard_event_efl.cc
+@@ -2,23 +2,32 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
++#include "content/browser/renderer_host/web_input_event_factory_efl.h"
+ #include "content/public/browser/native_web_keyboard_event.h"
+-#include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
+-
+ namespace content {
+-NativeWebKeyboardEvent::NativeWebKeyboardEvent() {
++NativeWebKeyboardEvent::NativeWebKeyboardEvent()
++    : os_event(NULL),
++      skip_in_browser(false) {
+ }
+-NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event) {
++NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
++    : WebKeyboardEvent(content::keyboardEvent(native_event)),
++      skip_in_browser(false) {
+ }
+-NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent&) {
++NativeWebKeyboardEvent::NativeWebKeyboardEvent(
++    const NativeWebKeyboardEvent& other)
++    : WebKeyboardEvent(other),
++      skip_in_browser(other.skip_in_browser) {
+ }
+ NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
+     const NativeWebKeyboardEvent& other) {
++  WebKeyboardEvent::operator=(other);
++
++  skip_in_browser = other.skip_in_browser;
+   return *this;
+ }
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 9118002..9858418 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -29,6 +29,7 @@
+ #include "content/browser/renderer_host/render_view_host_delegate.h"
+ #include "content/browser/renderer_host/render_view_host_impl.h"
+ #include "content/browser/renderer_host/window_utils_efl.h"
++#include "content/browser/renderer_host/web_input_event_factory_efl.h"
+ #include "content/common/edit_command.h"
+ #include "content/common/gpu/gpu_messages.h"
+ #include "content/public/browser/browser_context.h"
+@@ -42,6 +43,7 @@
+ #include "ui/base/text/text_elider.h"
+ #include "ui/base/x/active_window_watcher_x.h"
+ #include "ui/base/x/x11_util.h"
++#include "ui/gfx/efl_event.h"
+ #include "ui/gfx/preserve_window_efl.h"
+ #include "webkit/plugins/npapi/webplugin.h"
+@@ -100,37 +102,43 @@ RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
+   UnlockMouse();
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) {
+-  return false;
++void RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* mouse_down) {
++  host_->ForwardMouseEvent(content::mouseEvent(mouse_down));
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) {
+-  return false;
++void RenderWidgetHostViewEfl::PreserveWindowMouseUp(Evas_Event_Mouse_Up* mouse_up) {
++  host_->ForwardMouseEvent(content::mouseEvent(mouse_up));
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) {
+-return false;
++void RenderWidgetHostViewEfl::PreserveWindowMouseMove(Evas_Event_Mouse_Move* mouse_move) {
++  host_->ForwardMouseEvent(content::mouseEvent(mouse_move));
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) {
+-  return false;
++void RenderWidgetHostViewEfl::PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* mouse_wheel) {
++  host_->ForwardWheelEvent(content::mouseWheelEvent(mouse_wheel));
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowKeyDown(Evas_Event_Key_Down* event) {
+-  return false;
++void RenderWidgetHostViewEfl::PreserveWindowKeyDown(Evas_Event_Key_Down* key_down) {
++  gfx::EflEvent event = gfx::EflEvent(gfx::EflEvent::EventTypeKeyDown,
++                                           key_down);
++  host_->ForwardKeyboardEvent(NativeWebKeyboardEvent(&event));
+ }
+-bool RenderWidgetHostViewEfl::PreserveWindowKeyUp(Evas_Event_Key_Up* event) {
+-  return false;
++void RenderWidgetHostViewEfl::PreserveWindowKeyUp(Evas_Event_Key_Up* key_up) {
++  gfx::EflEvent event = gfx::EflEvent(gfx::EflEvent::EventTypeKeyUp,
++                                           key_up);
++  host_->ForwardKeyboardEvent(NativeWebKeyboardEvent(&event));
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowFocusIn() {
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowFocusOut() {
++//  root_window_host_delegate_->OnHostLostMouseGrab();
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowShow() {
++//  root_window_host_delegate_->OnHostActivated();
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowHide() {
+@@ -291,7 +299,6 @@ void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& cursor) {
+ }
+ void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
+-
+ }
+ void RenderWidgetHostViewEfl::TextInputStateChanged(
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.h b/content/browser/renderer_host/render_widget_host_view_efl.h
+index 617bce9..e20f51b 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.h
++++ b/content/browser/renderer_host/render_widget_host_view_efl.h
+@@ -18,13 +18,11 @@
+ #include "ipc/ipc_sender.h"
+ #include "ui/base/animation/animation_delegate.h"
+ #include "ui/base/animation/slide_animation.h"
+-//#include "ui/base/x/active_window_watcher_x_observer.h"
+ #include "ui/gfx/native_widget_types.h"
+ #include "ui/gfx/point.h"
+ #include "ui/gfx/preserve_window_delegate_efl.h"
+ #include "ui/gfx/rect.h"
+ #include "webkit/glue/webcursor.h"
+-//#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
+ namespace gfx {
+ class PreserveWindow;
+@@ -47,12 +45,12 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+   virtual ~RenderWidgetHostViewEfl();
+   // PreserveWindowDelegate implementation.
+-  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event);
+-  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event);
+-  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event);
+-  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event);
+-  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event);
+-  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event);
++  virtual void PreserveWindowMouseDown(Evas_Event_Mouse_Down* event);
++  virtual void PreserveWindowMouseUp(Evas_Event_Mouse_Up* event);
++  virtual void PreserveWindowMouseMove(Evas_Event_Mouse_Move* event);
++  virtual void PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event);
++  virtual void PreserveWindowKeyDown(Evas_Event_Key_Down* event);
++  virtual void PreserveWindowKeyUp(Evas_Event_Key_Up* event);
+   virtual void PreserveWindowFocusIn();
+   virtual void PreserveWindowFocusOut();
+   virtual void PreserveWindowShow();
+diff --git a/content/browser/renderer_host/web_input_event_factory_efl.cc b/content/browser/renderer_host/web_input_event_factory_efl.cc
+new file mode 100644
+index 0000000..66df8a7
+--- /dev/null
++++ b/content/browser/renderer_host/web_input_event_factory_efl.cc
+@@ -0,0 +1,417 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "base/logging.h"
++#include "base/time.h"
++#include "base/string_number_conversions.h"
++#include "base/string_util.h"
++#include "base/utf_string_conversions.h"
++#include "content/browser/renderer_host/web_input_event_factory_efl.h"
++#include "content/public/browser/native_web_keyboard_event.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
++#include "ui/base/events/event_constants.h"
++#include "ui/base/keycodes/keyboard_codes_posix.h"
++#include "ui/gfx/efl_event.h"
++
++#include <Evas.h>
++#include <map>
++
++namespace content {
++
++// Taken from web_input_event_aura.h
++const int kPixelsPerTick = 53;
++
++// Keycode map efl->windows vkeys.
++static std::map<std::string, ui::KeyboardCode> efl_keycode_map;
++
++static int eflModifierToWebEventModifiers(const Evas_Modifier* efl_modidier,
++                                          int buttons = 0) {
++  int modifiers = 0;
++  // FIXME: check what else we need to handle from WebKit::WebInputEvent::Modifiers
++  if (evas_key_modifier_is_set(efl_modidier, "Shift"))
++    modifiers |= WebKit::WebInputEvent::ShiftKey;
++  if (evas_key_modifier_is_set(efl_modidier, "Control"))
++    modifiers |= WebKit::WebInputEvent::ControlKey;
++  if (evas_key_modifier_is_set(efl_modidier, "Alt"))
++    modifiers |= WebKit::WebInputEvent::AltKey;
++  if (evas_key_modifier_is_set(efl_modidier, "Meta"))
++    modifiers |= WebKit::WebInputEvent::MetaKey;
++  if(buttons & 1)
++    modifiers |= WebKit::WebInputEvent::LeftButtonDown;
++  if(buttons & 2)
++    modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
++  if(buttons & 3)
++    modifiers |= WebKit::WebInputEvent::RightButtonDown;
++  return modifiers;
++}
++
++static int clickCountFromEflFlags(unsigned int flags)
++{
++    if (flags & EVAS_BUTTON_TRIPLE_CLICK)
++        return 3;
++    else if (flags & EVAS_BUTTON_DOUBLE_CLICK)
++        return 2;
++    else
++        return 1;
++}
++
++template<typename T>
++WebKit::WebMouseEvent toWebMouseEvent(WebKit::WebInputEvent::Type type, T* event)
++{
++  WebKit::WebMouseEvent result;
++
++  result.timeStampSeconds = base::Time::UnixEpoch().ToDoubleT();
++  result.modifiers = eflModifierToWebEventModifiers(event->modifiers, event->button);
++  result.x = event->canvas.x;
++  result.y = event->canvas.y;
++  result.windowX = result.x;
++  result.windowY = result.y;
++  // FIXME: initialise global position.
++  //  result.globalX = ;
++  //  result.globalY = ;
++  result.clickCount = clickCountFromEflFlags(event->flags);
++  result.type = type;
++  result.button = static_cast<WebKit::WebMouseEvent::Button>(event->button - 1);
++
++  return result;
++}
++
++static inline void addKey(std::string key, ui::KeyboardCode key_code)
++{
++  efl_keycode_map.insert(std::pair<std::string, ui::KeyboardCode>(key, key_code));
++}
++
++static inline void addRangeToKeycodeMap(const char from, const char to, int rangeStart)
++{
++  for (char c = from; c <= to; c++) {
++    addKey(std::string(1,c), (ui::KeyboardCode)rangeStart++);
++  }
++}
++
++static void createEflToWindowsKeyMap()
++{
++  // Unmapped codes.
++
++  // VKEY_CLEAR = 0x0C,
++  // VKEY_MENU = 0x12,
++  // VKEY_PAUSE = 0x13,
++  // VKEY_CAPITAL = 0x14,
++  // VKEY_KANA = 0x15,
++  // VKEY_HANGUL = 0x15,
++  // VKEY_JUNJA = 0x17,
++  // VKEY_FINAL = 0x18,
++  // VKEY_HANJA = 0x19,
++  // VKEY_KANJI = 0x19,
++  // VKEY_CONVERT = 0x1C,
++  // VKEY_NONCONVERT = 0x1D,
++  // VKEY_ACCEPT = 0x1E,
++  // VKEY_MODECHANGE = 0x1F,
++  // VKEY_SELECT = 0x29,
++  // VKEY_EXECUTE = 0x2B,
++  // VKEY_SNAPSHOT = 0x2C,
++  // VKEY_HELP = 0x2F,
++  // VKEY_LWIN = 0x5B,
++  // VKEY_COMMAND = VKEY_LWIN,  // Provide the Mac name for convenience.
++  // VKEY_RWIN = 0x5C,
++  // VKEY_APPS = 0x5D,
++  // VKEY_SLEEP = 0x5F,
++  // VKEY_SEPARATOR = 0x6C,
++  // VKEY_F13 = 0x7C,
++  // VKEY_F14 = 0x7D,
++  // VKEY_F15 = 0x7E,
++  // VKEY_F16 = 0x7F,
++  // VKEY_F17 = 0x80,
++  // VKEY_F18 = 0x81,
++  // VKEY_F19 = 0x82,
++  // VKEY_F20 = 0x83,
++  // VKEY_F21 = 0x84,
++  // VKEY_F22 = 0x85,
++  // VKEY_F23 = 0x86,
++  // VKEY_F24 = 0x87,
++  // VKEY_LMENU = 0xA4,
++  // VKEY_RMENU = 0xA5,
++  // VKEY_BROWSER_BACK = 0xA6,
++  // VKEY_BROWSER_FORWARD = 0xA7,
++  // VKEY_BROWSER_REFRESH = 0xA8,
++  // VKEY_BROWSER_STOP = 0xA9,
++  // VKEY_BROWSER_SEARCH = 0xAA,
++  // VKEY_BROWSER_FAVORITES = 0xAB,
++  // VKEY_BROWSER_HOME = 0xAC,
++  // VKEY_VOLUME_MUTE = 0xAD,
++  // VKEY_VOLUME_DOWN = 0xAE,
++  // VKEY_VOLUME_UP = 0xAF,
++  // VKEY_MEDIA_NEXT_TRACK = 0xB0,
++  // VKEY_MEDIA_PREV_TRACK = 0xB1,
++  // VKEY_MEDIA_STOP = 0xB2,
++  // VKEY_MEDIA_PLAY_PAUSE = 0xB3,
++  // VKEY_MEDIA_LAUNCH_MAIL = 0xB4,
++  // VKEY_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5,
++  // VKEY_MEDIA_LAUNCH_APP1 = 0xB6,
++  // VKEY_MEDIA_LAUNCH_APP2 = 0xB7,
++  // VKEY_OEM_1 = 0xBA,
++  // VKEY_OEM_PLUS = 0xBB,
++  // VKEY_OEM_COMMA = 0xBC,
++  // VKEY_OEM_MINUS = 0xBD,
++  // VKEY_OEM_PERIOD = 0xBE,
++  // VKEY_OEM_2 = 0xBF,
++  // VKEY_OEM_3 = 0xC0,
++  // VKEY_OEM_4 = 0xDB,
++  // VKEY_OEM_5 = 0xDC,
++  // VKEY_OEM_6 = 0xDD,
++  // VKEY_OEM_7 = 0xDE,
++  // VKEY_OEM_8 = 0xDF,
++  // VKEY_OEM_102 = 0xE2,
++  // VKEY_PROCESSKEY = 0xE5,
++  // VKEY_PACKET = 0xE7,
++  // VKEY_DBE_SBCSCHAR = 0xF3,
++  // VKEY_DBE_DBCSCHAR = 0xF4,
++  // VKEY_ATTN = 0xF6,
++  // VKEY_CRSEL = 0xF7,
++  // VKEY_EXSEL = 0xF8,
++  // VKEY_EREOF = 0xF9,
++  // VKEY_PLAY = 0xFA,
++  // VKEY_ZOOM = 0xFB,
++  // VKEY_NONAME = 0xFC,
++  // VKEY_PA1 = 0xFD,
++  // VKEY_OEM_CLEAR = 0xFE,
++
++  addKey(std::string("BackSpace"), ui::VKEY_BACK);
++  addKey(std::string("Tab"), ui::VKEY_TAB);
++  addKey(std::string("ISO_Left_Tab"), ui::VKEY_BACKTAB);
++  addKey(std::string("Return"), ui::VKEY_RETURN);
++  addKey(std::string("Escape"), ui::VKEY_ESCAPE);
++  addKey(std::string("space"), ui::VKEY_SPACE);
++  addKey(std::string("Prior"), ui::VKEY_PRIOR);
++  addKey(std::string("KP_Prior"), ui::VKEY_PRIOR);
++  addKey(std::string("Next"), ui::VKEY_NEXT);
++  addKey(std::string("Next"), ui::VKEY_NEXT);
++  addKey(std::string("End"), ui::VKEY_END);
++  addKey(std::string("KP_End"), ui::VKEY_END);
++  addKey(std::string("Home"), ui::VKEY_HOME);
++  addKey(std::string("KP_Home"), ui::VKEY_HOME);
++  addKey(std::string("Left"), ui::VKEY_LEFT);
++  addKey(std::string("KP_Left"), ui::VKEY_LEFT);
++  addKey(std::string("Up"), ui::VKEY_UP);
++  addKey(std::string("KP_Up"), ui::VKEY_UP);
++  addKey(std::string("Right"), ui::VKEY_RIGHT);
++  addKey(std::string("KP_Rright"), ui::VKEY_RIGHT);
++  addKey(std::string("Down"), ui::VKEY_DOWN);
++  addKey(std::string("KP_Down"), ui::VKEY_DOWN);
++  addKey(std::string("Print"), ui::VKEY_PRINT);
++  addKey(std::string("Insert"), ui::VKEY_INSERT);
++  addKey(std::string("KP_Insert"), ui::VKEY_INSERT);
++  addKey(std::string("Delete"), ui::VKEY_DELETE);
++  addKey(std::string("KP_Delete"), ui::VKEY_DELETE);
++  addKey(std::string("Shift_L"), ui::VKEY_LSHIFT);
++  addKey(std::string("Shift_R"), ui::VKEY_RSHIFT);
++  addKey(std::string("Control_R"), ui::VKEY_RCONTROL);
++  addKey(std::string("Control_L"), ui::VKEY_LCONTROL);
++  addKey(std::string("KP_Multiply"), ui::VKEY_MULTIPLY);
++  addKey(std::string("KP_Add"), ui::VKEY_ADD);
++  addKey(std::string("KP_Subtract"), ui::VKEY_SUBTRACT);
++  addKey(std::string("KP_Decimal"), ui::VKEY_DECIMAL);
++  addKey(std::string("KP_Divide"), ui::VKEY_DIVIDE);
++  addKey(std::string("Num_Lock"), ui::VKEY_NUMLOCK);
++  addKey(std::string("Scroll_Lock"), ui::VKEY_SCROLL);
++
++  // Numpad 0-9
++  for (int i = 0; i < 9; i++) {
++    addKey(std::string("KP_") + base::IntToString(i), (ui::KeyboardCode)(ui::VKEY_NUMPAD0 + i));
++  }
++
++  // F1-F12
++  for (int i = 0; i < 12; i++) {
++    addKey(std::string("F") + base::IntToString(i), (ui::KeyboardCode)(ui::VKEY_F1 + i));
++  }
++
++  addRangeToKeycodeMap('0', '9', ui::VKEY_0);
++  addRangeToKeycodeMap('a', 'z', ui::VKEY_A);
++  addRangeToKeycodeMap('A', 'Z', ui::VKEY_A);
++}
++
++// temporarily copied from WebKeyboardEvent::windowsKeyCodeWithoutLocation
++static int windowsKeyCodeWithoutLocation(ui::KeyboardCode keycode)
++{
++    switch (keycode) {
++    case ui::VKEY_LCONTROL:
++    case ui::VKEY_RCONTROL:
++        return ui::VKEY_CONTROL;
++    case ui::VKEY_LSHIFT:
++    case ui::VKEY_RSHIFT:
++        return ui::VKEY_SHIFT;
++    case ui::VKEY_LMENU:
++    case ui::VKEY_RMENU:
++        return ui::VKEY_MENU;
++    default:
++        return keycode;
++    }
++}
++
++// temporarily copied from WebKeyboardEvent::windowsKeyCodeWithoutLocation
++static int locationModifiersFromWindowsKeyCode(ui::KeyboardCode keycode)
++{
++    switch (keycode) {
++    case ui::VKEY_LCONTROL:
++    case ui::VKEY_LSHIFT:
++    case ui::VKEY_LMENU:
++    case ui::VKEY_LWIN:
++        return WebKit::WebKeyboardEvent::IsLeft;
++    case ui::VKEY_RCONTROL:
++    case ui::VKEY_RSHIFT:
++    case ui::VKEY_RMENU:
++    case ui::VKEY_RWIN:
++        return WebKit::WebKeyboardEvent::IsRight;
++    default:
++        return 0;
++    }
++}
++
++static bool setKeyText(ui::KeyboardCode code,
++                       WebKit::WebKeyboardEvent& webkit_event,
++                       const char* efl_event_string)
++{
++
++  bool rawKeyEvent = true;
++
++  switch (code) {
++    case ui::VKEY_RETURN:
++      webkit_event.unmodifiedText[0] = '\r';
++      break;
++    case ui::VKEY_BACK:
++      webkit_event.unmodifiedText[0] = '\x8';
++      break;
++    case ui::VKEY_TAB:
++      webkit_event.unmodifiedText[0] = '\t';
++      break;
++    default:
++      if (efl_event_string) {
++        base::string16 out_str;
++        bool success = UTF8ToUTF16(efl_event_string, strlen(efl_event_string), &out_str);
++        if (success) {
++          webkit_event.unmodifiedText[0] = out_str[0];
++          rawKeyEvent = false;
++        }
++      }
++  }
++
++  return rawKeyEvent;
++}
++
++ui::KeyboardCode windowsKeyboardCodeFromEvasKeyEventName(const char* eventName)
++{
++  if (efl_keycode_map.empty()) {
++    createEflToWindowsKeyMap();
++  }
++
++  const std::map<std::string, ui::KeyboardCode>::iterator it =
++                                   efl_keycode_map.find(std::string(eventName));
++  return it != efl_keycode_map.end() ? it->second : ui::VKEY_UNKNOWN;
++}
++
++template<typename T>
++WebKit::WebKeyboardEvent toWebKeyboardEvent(T* event,
++                                            gfx::EflEvent::EflEventType type)
++{
++  WebKit::WebKeyboardEvent result;
++
++  result.timeStampSeconds = event->timestamp / 1000;
++  result.modifiers = eflModifierToWebEventModifiers(event->modifiers);
++  ui::KeyboardCode windowsKeyCode = windowsKeyboardCodeFromEvasKeyEventName(event->keyname);
++  result.windowsKeyCode = windowsKeyCodeWithoutLocation(windowsKeyCode);
++  result.modifiers |= locationModifiersFromWindowsKeyCode(windowsKeyCode);
++  bool is_raw_key = setKeyText(windowsKeyCode, result, event->string);
++
++  if (type == gfx::EflEvent::EventTypeKeyDown) {
++    result.type = is_raw_key ? WebKit::WebInputEvent::RawKeyDown :
++                               WebKit::WebInputEvent::KeyDown;
++  } else {
++    result.type = WebKit::WebInputEvent::KeyUp;
++  }
++
++  result.text[0] = result.unmodifiedText[0];
++
++  result.setKeyIdentifierFromWindowsKeyCode();
++
++  if (event->key && StartsWithASCII(std::string(event->key), std::string("KP_"), true))
++    result.modifiers |= WebKit::WebInputEvent::IsKeyPad;
++
++  return result;
++}
++
++WebKit::WebKeyboardEvent keyboardEvent(gfx::NativeEvent event)
++{
++  DCHECK(event);
++
++  switch(event->eventType()) {
++    case gfx::EflEvent::EventTypeKeyUp:
++      return toWebKeyboardEvent(static_cast<Evas_Event_Key_Up*>(event->eflEvent()),
++                                gfx::EflEvent::EventTypeKeyUp);
++    case gfx::EflEvent::EventTypeKeyDown:
++      return toWebKeyboardEvent(static_cast<Evas_Event_Key_Down*>(event->eflEvent()),
++                                gfx::EflEvent::EventTypeKeyDown);
++    default:
++      NOTREACHED();
++  }
++
++  return WebKit::WebKeyboardEvent();
++}
++
++WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Down* mouse_down)
++{
++  DCHECK(mouse_down);
++  return toWebMouseEvent(WebKit::WebInputEvent::MouseDown, mouse_down);
++}
++
++WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Up* mouse_up)
++{
++  DCHECK(mouse_up);
++  return toWebMouseEvent(WebKit::WebInputEvent::MouseUp, mouse_up);
++}
++
++WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Move* mouse_move)
++{
++  DCHECK(mouse_move);
++
++  WebKit::WebMouseEvent result;
++
++  result.timeStampSeconds = base::Time::UnixEpoch().ToDoubleT();
++  result.modifiers = eflModifierToWebEventModifiers(mouse_move->modifiers, mouse_move->buttons);
++  result.x = mouse_move->cur.canvas.x;
++  result.y = mouse_move->cur.canvas.y;
++  result.windowX = result.x;
++  result.windowY = result.y;
++  result.clickCount = 0;
++  result.type = WebKit::WebInputEvent::MouseMove;
++  result.button = static_cast<WebKit::WebMouseEvent::Button>(mouse_move->buttons - 1);
++
++  return result;
++}
++
++WebKit::WebMouseWheelEvent mouseWheelEvent(Evas_Event_Mouse_Wheel* mouse_wheel)
++{
++  DCHECK(mouse_wheel);
++
++  int x_offset = 0;
++  int y_offset = 0;
++  if (mouse_wheel->direction == 0) {
++    y_offset = -mouse_wheel->z;
++  } else if (mouse_wheel->direction == 1) {
++    x_offset = -mouse_wheel->z;
++  }
++
++  WebKit::WebMouseWheelEvent event;
++
++  event.type = WebKit::WebInputEvent::MouseWheel;
++  event.button = WebKit::WebMouseEvent::ButtonNone;
++  event.modifiers = eflModifierToWebEventModifiers(mouse_wheel->modifiers);
++  event.timeStampSeconds = base::Time::UnixEpoch().ToDoubleT();
++  event.deltaX = x_offset * kPixelsPerTick;
++  event.deltaY = y_offset * kPixelsPerTick;
++  event.wheelTicksX = x_offset;
++  event.wheelTicksY = y_offset;
++
++  return event;
++}
++
++} // namespace content
+diff --git a/content/browser/renderer_host/web_input_event_factory_efl.h b/content/browser/renderer_host/web_input_event_factory_efl.h
+new file mode 100644
+index 0000000..47e76df
+--- /dev/null
++++ b/content/browser/renderer_host/web_input_event_factory_efl.h
+@@ -0,0 +1,32 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef CONTENT_BROWSER_RENDERER_HOST_WEB_INPUT_EVENT_FACTORY_EFL_H_
++#define CONTENT_BROWSER_RENDERER_HOST_WEB_INPUT_EVENT_FACTORY_EFL_H_
++
++#include "content/common/content_export.h"
++#include "ui/gfx/native_widget_types.h"
++
++typedef struct _Evas_Event_Mouse_Down Evas_Event_Mouse_Down;
++typedef struct _Evas_Event_Mouse_Up Evas_Event_Mouse_Up;
++typedef struct _Evas_Event_Mouse_Move Evas_Event_Mouse_Move;
++typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel;
++
++namespace WebKit {
++struct WebMouseEvent;
++struct WebMouseWheelEvent;
++struct WebKeyboardEvent;
++}
++
++namespace content {
++
++CONTENT_EXPORT WebKit::WebKeyboardEvent keyboardEvent(gfx::NativeEvent);
++CONTENT_EXPORT WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Down*);
++CONTENT_EXPORT WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Up*);
++CONTENT_EXPORT WebKit::WebMouseEvent mouseEvent(Evas_Event_Mouse_Move*);
++CONTENT_EXPORT WebKit::WebMouseWheelEvent mouseWheelEvent(Evas_Event_Mouse_Wheel*);
++
++} // namespace content
++
++#endif // CONTENT_BROWSER_RENDERER_HOST_WEB_INPUT_EVENT_FACTORY_EFL_H_
+diff --git a/content/content_browser.gypi b/content/content_browser.gypi
+index 1484aaa..92aed8d 100644
+--- a/content/content_browser.gypi
++++ b/content/content_browser.gypi
+@@ -757,9 +757,9 @@
+     'browser/renderer_host/media/webrtc_logging_handler_host.h',
+     'browser/renderer_host/native_web_keyboard_event_android.cc',
+     'browser/renderer_host/native_web_keyboard_event_aura.cc',
+-    'browser/renderer_host/native_web_keyboard_event.cc',
+     'browser/renderer_host/native_web_keyboard_event_efl.cc',
+-    'browser/renderer_host/native_web_keyboard_event_gtk.cc',
++    'browser/renderer_host/native_web_keyboard_event.cc',
++    'browser/renderer_host/native_web_keyboard_event_gtk.cc'
+     'browser/renderer_host/native_web_keyboard_event_mac.mm',
+     'browser/renderer_host/native_web_keyboard_event_win.cc',
+     'browser/renderer_host/overscroll_configuration.cc',
+@@ -873,6 +873,8 @@
+     'browser/renderer_host/web_input_event_aura.h',
+     'browser/renderer_host/web_input_event_aurawin.cc',
+     'browser/renderer_host/web_input_event_aurax11.cc',
++    'browser/renderer_host/web_input_event_factory_efl.h',
++    'browser/renderer_host/web_input_event_factory_efl.cc',
+     'browser/renderer_host/window_utils_efl.h',
+     'browser/renderer_host/window_utils_efl.cc',
+     'browser/resolve_proxy_msg_helper.cc',
+@@ -1178,6 +1180,7 @@
+       'sources/': [
+         ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
+         ['exclude', 'browser/web_contents/web_contents_view_gtk.h'],
++        ['exclude', 'browser/renderer_host/native_web_keyboard_event_gtk.cc'],
+         ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.cc'],
+         ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.h'],
+         ['exclude', 'browser/renderer_host/gtk_im_context_wrapper.cc'],
+diff --git a/ui/gfx/efl_event.h b/ui/gfx/efl_event.h
+new file mode 100644
+index 0000000..07ecb0f
+--- /dev/null
++++ b/ui/gfx/efl_event.h
+@@ -0,0 +1,33 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef UI_GFX_EFL_EVENT_H_
++#define UI_GFX_EFL_EVENT_H_
++
++#include "ui/base/ui_export.h"
++
++namespace gfx {
++
++class UI_EXPORT EflEvent {
++  public:
++
++  enum EflEventType {
++    EventTypeKeyUp,
++    EventTypeKeyDown
++  };
++
++  EflEvent(EflEventType type, void* efl_event) : type_(type),
++                                                 efl_event_(efl_event) {}
++
++  EflEventType eventType() const { return type_; }
++  void* eflEvent() { return efl_event_; }
++
++  private:
++    EflEventType type_;
++    void* efl_event_;
++};
++
++} // namespace gfx
++
++#endif // UI_GFX_EFL_EVENT_H_
+diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
+index 8916610..b60a27e 100644
+--- a/ui/gfx/native_widget_types.h
++++ b/ui/gfx/native_widget_types.h
+@@ -107,6 +107,9 @@ typedef struct _GdkRegion GdkRegion;
+ typedef struct _GtkWidget GtkWidget;
+ typedef struct _GtkWindow GtkWindow;
+ #elif defined(TOOLKIT_EFL)
++namespace gfx {
++class EflEvent;
++}
+ typedef struct _Evas_Object Evas_Object;
+ #elif defined(OS_ANDROID)
+ struct ANativeWindow;
+@@ -152,7 +155,7 @@ typedef void* NativeCursor;
+ typedef Evas_Object* NativeView;
+ typedef void* NativeRegion;
+ typedef Evas_Object* NativeWindow;
+-typedef void* NativeEvent;
++typedef EflEvent* NativeEvent;
+ #elif defined(OS_ANDROID)
+ typedef void* NativeCursor;
+ typedef ui::ViewAndroid* NativeView;
+diff --git a/ui/gfx/preserve_window_delegate_efl.h b/ui/gfx/preserve_window_delegate_efl.h
+index aa7863b..e75218f 100644
+--- a/ui/gfx/preserve_window_delegate_efl.h
++++ b/ui/gfx/preserve_window_delegate_efl.h
+@@ -18,12 +18,12 @@ namespace gfx {
+ // with their owning PreserveWindow.
+ class UI_EXPORT PreserveWindowDelegate {
+  public:
+-  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) = 0;
+-  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) = 0;
+-  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) = 0;
+-  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) = 0;
+-  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event) = 0;
+-  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event) = 0;
++  virtual void PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) = 0;
++  virtual void PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) = 0;
++  virtual void PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) = 0;
++  virtual void PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) = 0;
++  virtual void PreserveWindowKeyDown(Evas_Event_Key_Down* event) = 0;
++  virtual void PreserveWindowKeyUp(Evas_Event_Key_Up* event) = 0;
+   // Called when the windowing system activates the window.
+   virtual void PreserveWindowFocusIn() = 0;
+diff --git a/ui/ui.gyp b/ui/ui.gyp
+index e6c240e..059652c 100644
+--- a/ui/ui.gyp
++++ b/ui/ui.gyp
+@@ -703,6 +703,7 @@
+           'sources': [
+             'base/clipboard/clipboard_efl.cc',
+             'base/resource/resource_bundle_efl.cc',
++            'gfx/efl_event.h',
+             'gfx/efl_util.cc',
+             'gfx/efl_util.h',
+             'gfx/screen_efl.cc',
+-- 
+1.8.1.2
+
diff --git a/patchset/0005-Implement-efl-webview-library-and-example-launcher.patch b/patchset/0005-Implement-efl-webview-library-and-example-launcher.patch
new file mode 100644 (file)
index 0000000..314e407
--- /dev/null
@@ -0,0 +1,929 @@
+From 33d979ca744bb52d6c8490b9718ac6ee09f5ff7f Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Fri, 28 Jun 2013 14:25:43 +0300
+Subject: [PATCH 05/33] Implement efl webview library and example launcher.
+
+1. build efl_webview library
+make efl_webview
+
+2. build efl_webview_example executable
+make efl_webview_example
+
+Make sub process be able to launch
+Add process executable to launch sub process (i.e. gpu process, zygote)
+---
+ AUTHORS                                            |   1 +
+ base/run_loop.h                                    |   8 +-
+ build/all.gyp                                      |   1 +
+ .../browser/zygote_host/zygote_host_impl_linux.cc  |   6 +-
+ content/public/app/content_main_runner.h           |   3 +-
+ content/public/common/content_client.h             |   2 +-
+ efl_webview/DEPS                                   |   4 +
+ efl_webview/efl_webview.gyp                        | 134 +++++++++++++++++++++
+ efl_webview/examples/main.cc                       | 102 ++++++++++++++++
+ efl_webview/lib/browser_context_xwalk.h            |  30 +++++
+ efl_webview/lib/content_browser_client_xwalk.cc    |  60 +++++++++
+ efl_webview/lib/content_browser_client_xwalk.h     |  29 +++++
+ efl_webview/lib/process_main.cc                    |  24 ++++
+ efl_webview/lib/process_main.h                     |  16 +++
+ efl_webview/lib/web_runtime_context.cc             | 118 ++++++++++++++++++
+ efl_webview/lib/web_runtime_context.h              |  37 ++++++
+ efl_webview/lib/webview.cc                         |  91 ++++++++++++++
+ efl_webview/lib/webview.h                          |  40 ++++++
+ efl_webview/process/main.cc                        |  10 ++
+ 19 files changed, 708 insertions(+), 8 deletions(-)
+ create mode 100644 efl_webview/DEPS
+ create mode 100644 efl_webview/efl_webview.gyp
+ create mode 100644 efl_webview/examples/main.cc
+ create mode 100644 efl_webview/lib/browser_context_xwalk.h
+ create mode 100644 efl_webview/lib/content_browser_client_xwalk.cc
+ create mode 100644 efl_webview/lib/content_browser_client_xwalk.h
+ create mode 100644 efl_webview/lib/process_main.cc
+ create mode 100644 efl_webview/lib/process_main.h
+ create mode 100644 efl_webview/lib/web_runtime_context.cc
+ create mode 100644 efl_webview/lib/web_runtime_context.h
+ create mode 100644 efl_webview/lib/webview.cc
+ create mode 100644 efl_webview/lib/webview.h
+ create mode 100644 efl_webview/process/main.cc
+
+diff --git a/AUTHORS b/AUTHORS
+index a0e975c..d6978e6 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -251,3 +251,4 @@ Mihai Tica <mihai.o.tica@gmail.com>
+ Mihai Tica <mitica@adobe.com>
+ Bem Jones-Bey <bemajaniman@gmail.com>
+ Bem Jones-Bey <bjonesbe@adobe.com>
++Dongseong Hwang <dongseong.hwang@intel.com>
+diff --git a/base/run_loop.h b/base/run_loop.h
+index 380c8bf..469b8a7 100644
+--- a/base/run_loop.h
++++ b/base/run_loop.h
+@@ -72,6 +72,10 @@ class BASE_EXPORT RunLoop {
+   //   run_loop.Run();
+   base::Closure QuitClosure();
++  // Return false to abort the Run.
++  bool BeforeRun();
++  void AfterRun();
++
+  private:
+   friend class MessageLoop;
+ #if defined(OS_ANDROID)
+@@ -86,10 +90,6 @@ class BASE_EXPORT RunLoop {
+   friend class base::MessagePumpUIApplication;
+ #endif
+-  // Return false to abort the Run.
+-  bool BeforeRun();
+-  void AfterRun();
+-
+   MessageLoop* loop_;
+   // WeakPtrFactory for QuitClosure safety.
+diff --git a/build/all.gyp b/build/all.gyp
+index 14d4888..9043af8 100644
+--- a/build/all.gyp
++++ b/build/all.gyp
+@@ -14,6 +14,7 @@
+         '../chrome/chrome.gyp:*',
+         '../content/content.gyp:*',
+         '../crypto/crypto.gyp:*',
++        '../efl_webview/efl_webview.gyp:*',
+         '../media/media.gyp:*',
+         '../net/net.gyp:*',
+         '../sdch/sdch.gyp:*',
+diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc
+index ba7884f8..1be62f0 100644
+--- a/content/browser/zygote_host/zygote_host_impl_linux.cc
++++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
+@@ -29,6 +29,7 @@
+ #include "content/browser/renderer_host/render_sandbox_host_linux.h"
+ #include "content/common/zygote_commands_linux.h"
+ #include "content/public/browser/content_browser_client.h"
++#include "content/public/common/child_process_host.h"
+ #include "content/public/common/content_switches.h"
+ #include "content/public/common/result_codes.h"
+ #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
+@@ -68,8 +69,9 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
+   DCHECK(!init_);
+   init_ = true;
+-  base::FilePath chrome_path;
+-  CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
++  int child_flags = ChildProcessHost::CHILD_NORMAL;
++  base::FilePath chrome_path = ChildProcessHost::GetChildPath(child_flags);
++  CHECK(!chrome_path.empty());
+   CommandLine cmd_line(chrome_path);
+   cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kZygoteProcess);
+diff --git a/content/public/app/content_main_runner.h b/content/public/app/content_main_runner.h
+index bed5ff2..992e0d0 100644
+--- a/content/public/app/content_main_runner.h
++++ b/content/public/app/content_main_runner.h
+@@ -8,6 +8,7 @@
+ #include <string>
+ #include "build/build_config.h"
++#include "content/common/content_export.h"
+ #if defined(OS_WIN)
+ #include <windows.h>
+@@ -22,7 +23,7 @@ namespace content {
+ class ContentMainDelegate;
+ // This class is responsible for content initialization, running and shutdown.
+-class ContentMainRunner {
++class CONTENT_EXPORT ContentMainRunner {
+  public:
+   virtual ~ContentMainRunner() {}
+diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
+index 198ecad..778fcac 100644
+--- a/content/public/common/content_client.h
++++ b/content/public/common/content_client.h
+@@ -60,7 +60,7 @@ CONTENT_EXPORT void SetContentClient(ContentClient* client);
+ #if defined(CONTENT_IMPLEMENTATION)
+ // Content's embedder API should only be used by content.
+-ContentClient* GetContentClient();
++CONTENT_EXPORT ContentClient* GetContentClient();
+ #endif
+ // Used for tests to override the relevant embedder interfaces. Each method
+diff --git a/efl_webview/DEPS b/efl_webview/DEPS
+new file mode 100644
+index 0000000..dd8d329
+--- /dev/null
++++ b/efl_webview/DEPS
+@@ -0,0 +1,4 @@
++include_rules = [
++  "+content",
++  "+net",
++]
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+new file mode 100644
+index 0000000..b4d25d3
+--- /dev/null
++++ b/efl_webview/efl_webview.gyp
+@@ -0,0 +1,134 @@
++{
++  'variables': {
++    'efl_webview_product_name': 'EFL WebView',
++    # TODO: define efl webview version format.
++    'cameo_version': '0.28.0.1',
++    'conditions': [
++      ['OS=="linux"', {
++       'use_custom_freetype%': 1,
++      }, {
++       'use_custom_freetype%': 0,
++      }],
++    ], # conditions
++  },
++  'targets': [
++    {
++      'target_name': 'efl_webview',
++      'type': '<(component)',
++      'variables': {
++        'chromium_code': 1,
++      },
++      'dependencies': [
++        '../base/base.gyp:base',
++        '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
++        '../build/temp_gyp/googleurl.gyp:googleurl',
++        '../content/content.gyp:content_app',
++        '../content/content.gyp:content_browser',
++        '../content/content.gyp:content_common',
++        '../content/content.gyp:content_gpu',
++        '../content/content.gyp:content_plugin',
++        '../content/content.gyp:content_ppapi_plugin',
++        '../content/content.gyp:content_renderer',
++        '../content/content.gyp:content_utility',
++        '../content/content.gyp:content_worker',
++        # BrowserContextXWalk depend on content_shell_lib
++        '../content/content.gyp:content_shell_lib',
++        '../content/content_resources.gyp:content_resources',
++        '../ipc/ipc.gyp:ipc',
++        '../media/media.gyp:media',
++        '../net/net.gyp:net',
++        '../net/net.gyp:net_resources',
++        '../skia/skia.gyp:skia',
++        '../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit',
++        '../ui/gl/gl.gyp:gl',
++        '../ui/ui.gyp:ui',
++        '../v8/tools/gyp/v8.gyp:v8',
++        '../webkit/support/webkit_support.gyp:webkit_resources',
++        '../webkit/support/webkit_support.gyp:webkit_support',
++      ],
++      'include_dirs': [
++        '..',
++      ],
++      'sources': [
++        'lib/content_browser_client_xwalk.cc',
++        'lib/content_browser_client_xwalk.h',
++        'lib/browser_context_xwalk.h',
++        'lib/process_main.cc',
++        'lib/process_main.h',
++        'lib/web_runtime_context.cc',
++        'lib/web_runtime_context.h',
++        'lib/webview.cc',
++        'lib/webview.h',
++      ],
++      'conditions': [
++        ['OS=="linux"', {
++          'dependencies': [
++            '../build/linux/system.gyp:fontconfig',
++          ],
++        }],  # OS=="linux"
++        ['os_posix==1 and linux_use_tcmalloc==1', {
++          'dependencies': [
++            # This is needed by content/app/content_main_runner.cc
++            '../base/allocator/allocator.gyp:allocator',
++          ],
++        }],  # os_posix==1 and linux_use_tcmalloc==1
++        ['use_custom_freetype==1', {
++          'dependencies': [
++             '../third_party/freetype2/freetype2.gyp:freetype2',
++          ],
++        }],  # use_custom_freetype==1
++        ['toolkit_uses_gtk == 1', {
++          'dependencies': [
++            '<(DEPTH)/build/linux/system.gyp:gtk',
++          ],
++        }],  # toolkit_uses_gtk
++        ['toolkit_uses_efl == 1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++        }],
++      ],
++    },
++    {
++      'target_name': 'efl_webview_example',
++      'type': 'executable',
++      'dependencies': [
++        'efl_webview',
++        'efl_process',
++      ],
++      'include_dirs': [
++        '..',
++      ],
++      'sources': [
++        'examples/main.cc',
++      ],
++      'conditions': [
++        ['toolkit_uses_efl == 1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++        }],
++      ],
++    },
++    {
++      'target_name': 'efl_process',
++      'type': 'executable',
++      'dependencies': [
++        'efl_webview',
++      ],
++      'include_dirs': [
++        '..',
++      ],
++      'sources': [
++        'process/main.cc',
++      ],
++      'conditions': [
++        ['toolkit_uses_efl == 1', {
++          'dependencies': [
++            '../build/linux/system.gyp:efl',
++          ],
++        }],
++      ],
++    },
++  ],
++}
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+new file mode 100644
+index 0000000..ee610fb
+--- /dev/null
++++ b/efl_webview/examples/main.cc
+@@ -0,0 +1,102 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Elementary.h>
++
++#include "efl_webview/lib/process_main.h"
++#include "efl_webview/lib/webview.h"
++
++static const char APP_NAME[] = "EFL WebView Example";
++
++static int window_width = 800;
++static int window_height = 600;
++
++static void
++on_back_button_clicked(void *user_data, Evas_Object *back_button, void *event_info)
++{
++  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
++  webview->Back();
++}
++
++static void
++on_forward_button_clicked(void *user_data, Evas_Object *forward_button, void *event_info)
++{
++  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
++  webview->Forward();
++}
++
++static void window_create()
++{
++  /* Create window */
++  Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window", APP_NAME);
++  elm_win_autodel_set(elm_window, EINA_TRUE);
++
++  /* Create vertical layout */
++  Evas_Object* vertical_layout = elm_box_add(elm_window);
++  elm_box_padding_set(vertical_layout, 0, 2);
++  evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  elm_win_resize_object_add(elm_window, vertical_layout);
++  evas_object_show(vertical_layout);
++
++  /* Create horizontal layout for top bar */
++  Evas_Object* horizontal_layout = elm_box_add(elm_window);
++  elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
++  evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
++  evas_object_size_hint_align_set(horizontal_layout, EVAS_HINT_FILL, 0.0);
++  elm_box_pack_end(vertical_layout, horizontal_layout);
++  evas_object_show(horizontal_layout);
++
++  /* Create Back button */
++  Evas_Object* back_button = elm_button_add(elm_window);
++  elm_object_text_set(back_button, "BACK");
++  evas_object_size_hint_weight_set(back_button, 0.0, EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(back_button, 0.0, 0.5);
++  elm_box_pack_end(horizontal_layout, back_button);
++  evas_object_show(back_button);
++
++  /* Create Forward button */
++  Evas_Object* forward_button = elm_button_add(elm_window);
++  elm_object_text_set(forward_button, "FORWARD");
++  evas_object_size_hint_weight_set(forward_button, 0.0, EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(forward_button, 0.0, 0.5);
++  elm_box_pack_end(horizontal_layout, forward_button);
++  evas_object_show(forward_button);
++
++  /* Create WebView */
++  xwalk::WebView* webview_object = xwalk::WebView::Create(elm_window);
++  Evas_Object* webview = webview_object->EvasObject();
++  evas_object_size_hint_weight_set(webview, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(webview, EVAS_HINT_FILL, EVAS_HINT_FILL);
++  elm_box_pack_end(vertical_layout, webview);
++  evas_object_focus_set(webview, EINA_TRUE);
++  evas_object_show(webview);
++
++  evas_object_smart_callback_add(back_button, "clicked",
++                                 on_back_button_clicked, webview_object);
++  evas_object_smart_callback_add(forward_button, "clicked",
++                                 on_forward_button_clicked, webview_object);
++
++  evas_object_resize(elm_window, window_width, window_height);
++  evas_object_show(elm_window);
++}
++
++int main(int argc, char *argv[])
++{
++  // FIXME: Handle chrome command line and url.
++  // It is needed only in development stage.
++  xwalk::WebView::CommandLineInit(argc, argv);
++
++  elm_init(argc, argv);
++
++  elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
++
++  window_create();
++
++  elm_run();
++  elm_shutdown();
++
++  return 0;
++}
+diff --git a/efl_webview/lib/browser_context_xwalk.h b/efl_webview/lib/browser_context_xwalk.h
+new file mode 100644
+index 0000000..869fa82
+--- /dev/null
++++ b/efl_webview/lib/browser_context_xwalk.h
+@@ -0,0 +1,30 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIBBROWSER_CONTEXT_XWALK_H_
++#define EFL_WEBVIEW_LIBBROWSER_CONTEXT_XWALK_H_
++
++#include "content/shell/shell_browser_context.h"
++
++namespace xwalk {
++
++class BrowserContextXWalk : public content::ShellBrowserContext {
++ public:
++  BrowserContextXWalk()
++      : content::ShellBrowserContext(false)
++  { }
++  virtual ~BrowserContextXWalk() {}
++
++  net::URLRequestContextGetter* CreateRequestContext(
++      content::ProtocolHandlerMap* protocol_handlers) {
++    return content::ShellBrowserContext::CreateRequestContext(protocol_handlers);
++  }
++
++ private:
++  DISALLOW_COPY_AND_ASSIGN(BrowserContextXWalk);
++};
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIBBROWSER_CONTEXT_XWALK_H_
+diff --git a/efl_webview/lib/content_browser_client_xwalk.cc b/efl_webview/lib/content_browser_client_xwalk.cc
+new file mode 100644
+index 0000000..7a14c99
+--- /dev/null
++++ b/efl_webview/lib/content_browser_client_xwalk.cc
+@@ -0,0 +1,60 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/content_browser_client_xwalk.h"
++
++#include "content/public/browser/browser_main_parts.h"
++#include "content/public/common/main_function_params.h"
++#include "efl_webview/lib/browser_context_xwalk.h"
++#include "efl_webview/lib/web_runtime_context.h"
++
++namespace xwalk {
++
++class BrowserMainPartsXWalk : public content::BrowserMainParts
++{
++ public:
++  BrowserMainPartsXWalk(const content::MainFunctionParams& parameters)
++      : content::BrowserMainParts()
++      , parameters_(parameters)
++      , run_message_loop_(true)
++  { }
++
++  virtual void PreMainMessageLoopStart() OVERRIDE { }
++  virtual void PostMainMessageLoopStart() OVERRIDE { }
++  virtual void PreEarlyInitialization() OVERRIDE { }
++
++  virtual void PreMainMessageLoopRun() OVERRIDE {
++    if (parameters_.ui_task) {
++      parameters_.ui_task->Run();
++      delete parameters_.ui_task;
++      run_message_loop_ = false;
++    }
++  }
++
++  virtual bool MainMessageLoopRun(int* result_code) OVERRIDE {
++    return !run_message_loop_;
++  }
++
++  virtual void PostMainMessageLoopRun() OVERRIDE { }
++
++ private:
++  const content::MainFunctionParams& parameters_;
++  bool run_message_loop_;
++
++  DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsXWalk);
++};
++
++content::BrowserMainParts *ContentBrowserClientXWalk::CreateBrowserMainParts(
++    const content::MainFunctionParams &parameters) {
++  return new BrowserMainPartsXWalk(parameters);
++}
++
++net::URLRequestContextGetter* ContentBrowserClientXWalk::CreateRequestContext(
++    content::BrowserContext* content_browser_context,
++    content::ProtocolHandlerMap* protocol_handlers) {
++  DCHECK(content_browser_context == WebRuntimeContext::current()->BrowserContext());
++  return static_cast<BrowserContextXWalk*>(content_browser_context)->CreateRequestContext(protocol_handlers);
++}
++
++} // namespace xwalk
+diff --git a/efl_webview/lib/content_browser_client_xwalk.h b/efl_webview/lib/content_browser_client_xwalk.h
+new file mode 100644
+index 0000000..c5c235d
+--- /dev/null
++++ b/efl_webview/lib/content_browser_client_xwalk.h
+@@ -0,0 +1,29 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIBCONTENT_BROWSER_CLIENT_XWALK_H_
++#define EFL_WEBVIEW_LIBCONTENT_BROWSER_CLIENT_XWALK_H_
++
++#include "content/public/browser/content_browser_client.h"
++
++namespace xwalk {
++
++class ContentBrowserClientXWalk : public content::ContentBrowserClient {
++ public:
++  ContentBrowserClientXWalk() { }
++
++  // ContentBrowserClient overrides.
++  virtual content::BrowserMainParts* CreateBrowserMainParts(
++      const content::MainFunctionParams& parameters) OVERRIDE;
++  virtual net::URLRequestContextGetter* CreateRequestContext(
++      content::BrowserContext* browser_context,
++      content::ProtocolHandlerMap* protocol_handlers) OVERRIDE;
++
++ private:
++  DISALLOW_COPY_AND_ASSIGN(ContentBrowserClientXWalk);
++};
++
++} // namespace xwalk
++
++#endif // EFL_WEBVIEW_LIBCONTENT_BROWSER_CLIENT_XWALK_H_
+diff --git a/efl_webview/lib/process_main.cc b/efl_webview/lib/process_main.cc
+new file mode 100644
+index 0000000..132b35c
+--- /dev/null
++++ b/efl_webview/lib/process_main.cc
+@@ -0,0 +1,24 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/process_main.h"
++
++#include "base/command_line.h"
++#include "base/logging.h"
++#include "content/public/app/content_main.h"
++#include "content/public/common/content_switches.h"
++
++namespace xwalk {
++
++int ProcessMain(int argc, char** argv) {
++  CommandLine::Init(argc, argv);
++  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
++  std::string process_type =
++      command_line.GetSwitchValueASCII(switches::kProcessType);
++  CHECK(process_type != "");
++
++  return content::ContentMain(argc, const_cast<const char**>(argv), 0);
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/process_main.h b/efl_webview/lib/process_main.h
+new file mode 100644
+index 0000000..8e47949
+--- /dev/null
++++ b/efl_webview/lib/process_main.h
+@@ -0,0 +1,16 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_PROCESS_MAIN_H_
++#define EFL_WEBVIEW_LIB_PROCESS_MAIN_H_
++
++#include <Eina.h>
++
++namespace xwalk {
++
++EAPI int ProcessMain(int argc, char** argv);
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIB_PROCESS_MAIN_H_
+diff --git a/efl_webview/lib/web_runtime_context.cc b/efl_webview/lib/web_runtime_context.cc
+new file mode 100644
+index 0000000..b2ad541
+--- /dev/null
++++ b/efl_webview/lib/web_runtime_context.cc
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
++ * Copyright (c) 2013 Intel Corporation. All rights reserved.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#include "efl_webview/lib/web_runtime_context.h"
++
++#include "base/base_paths.h"
++#include "base/command_line.h"
++#include "base/path_service.h"
++#include "content/public/app/content_main_delegate.h"
++#include "content/public/app/content_main_runner.h"
++#include "content/public/browser/browser_main_runner.h"
++#include "content/public/common/content_switches.h"
++#include "content/public/common/main_function_params.h"
++#include "efl_webview/lib/browser_context_xwalk.h"
++#include "efl_webview/lib/content_browser_client_xwalk.h"
++
++namespace xwalk {
++
++namespace {
++
++class ContentMainDelegateXWalk : public content::ContentMainDelegate {
++ public:
++  ContentMainDelegateXWalk() { }
++
++  content::ContentBrowserClient* CreateContentBrowserClient()   {
++    browser_client_.reset(new ContentBrowserClientXWalk);
++    return browser_client_.get();
++  }
++
++ private:
++  scoped_ptr<ContentBrowserClientXWalk> browser_client_;
++
++  DISALLOW_COPY_AND_ASSIGN(ContentMainDelegateXWalk);
++};
++
++WebRuntimeContext* g_context = 0;
++// TODO: it should be passed via build system.
++const char g_sub_process_name[] = "efl_process";
++
++void SubprocessPathInit() {
++  base::FilePath current_directory;
++  CHECK(PathService::Get(base::FILE_EXE, &current_directory));
++  current_directory = current_directory.DirName();
++
++  // TODO: use more elegant way.
++  base::FilePath subprocess_path(
++      current_directory.value() + "/" + g_sub_process_name);
++
++  CommandLine::ForCurrentProcess()->
++      AppendSwitchPath(switches::kBrowserSubprocessPath, subprocess_path);
++}
++
++} // namespace
++
++WebRuntimeContext::WebRuntimeContext() {
++  DCHECK(!g_context);
++  g_context = this;
++
++  static content::ContentMainRunner *runner = 0;
++  if (!runner) {
++    runner = content::ContentMainRunner::Create();
++    runner->Initialize(0, 0, new ContentMainDelegateXWalk);
++  }
++
++  SubprocessPathInit();
++
++  static content::BrowserMainRunner *browserRunner = 0;
++  if (!browserRunner) {
++    browserRunner = content::BrowserMainRunner::Create();
++    browserRunner->Initialize(content::MainFunctionParams(
++        *CommandLine::ForCurrentProcess()));
++  }
++
++  base::ThreadRestrictions::SetIOAllowed(true);
++
++  // Once the MessageLoop has been created, attach a top-level RunLoop.
++  run_loop_.reset(new base::RunLoop);
++  run_loop_->BeforeRun();
++
++  browser_context_.reset(new BrowserContextXWalk);
++}
++
++WebRuntimeContext::~WebRuntimeContext() {
++  run_loop_->AfterRun();
++
++  DCHECK(g_context == this);
++  g_context = 0;
++}
++
++scoped_refptr<WebRuntimeContext> WebRuntimeContext::current() {
++  scoped_refptr<WebRuntimeContext> current = g_context;
++  if (!current)
++    current = new WebRuntimeContext;
++  DCHECK(g_context == current);
++  return current;
++}
++
++content::BrowserContext* WebRuntimeContext::BrowserContext() {
++  return browser_context_.get();
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/web_runtime_context.h b/efl_webview/lib/web_runtime_context.h
+new file mode 100644
+index 0000000..a0341fe
+--- /dev/null
++++ b/efl_webview/lib/web_runtime_context.h
+@@ -0,0 +1,37 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIBWEB_RUNTIME_CONTEXT_H_
++#define EFL_WEBVIEW_LIBWEB_RUNTIME_CONTEXT_H_
++
++#include "base/basictypes.h"
++#include "base/memory/ref_counted.h"
++#include "base/memory/scoped_ptr.h"
++#include "base/run_loop.h"
++
++namespace content {
++class BrowserContext;
++}
++
++namespace xwalk {
++
++class WebRuntimeContext : public base::RefCounted<WebRuntimeContext> {
++ public:
++  static scoped_refptr<WebRuntimeContext> current();
++  content::BrowserContext* BrowserContext();
++
++ private:
++  friend class base::RefCounted<WebRuntimeContext>;
++  WebRuntimeContext();
++  ~WebRuntimeContext();
++
++  scoped_ptr<base::RunLoop> run_loop_;
++  scoped_ptr<content::BrowserContext> browser_context_;
++
++  DISALLOW_COPY_AND_ASSIGN(WebRuntimeContext);
++};
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIBWEB_RUNTIME_CONTEXT_H_
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+new file mode 100644
+index 0000000..510f452
+--- /dev/null
++++ b/efl_webview/lib/webview.cc
+@@ -0,0 +1,91 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/webview.h"
++
++#include <Elementary.h>
++#include "base/command_line.h"
++#include "content/browser/web_contents/web_contents_view_efl.h"
++#include "content/public/browser/web_contents.h"
++#include "content/public/browser/web_contents_delegate.h"
++#include "efl_webview/lib/web_runtime_context.h"
++
++namespace xwalk {
++
++namespace {
++const int g_window_width = 800;
++const int g_window_height = 600;
++
++class WebContentsDelegateXWalk : public content::WebContentsDelegate
++{
++ public:
++  explicit WebContentsDelegateXWalk(content::BrowserContext*);
++  content::WebContents* WebContents() { return web_contents_.get(); }
++
++ private:
++  scoped_ptr<content::WebContents> web_contents_;
++};
++
++WebContentsDelegateXWalk::WebContentsDelegateXWalk(
++    content::BrowserContext* browser_context)
++{
++  content::WebContents::CreateParams create_params(browser_context, 0);
++  create_params.initial_size = gfx::Size(g_window_width, g_window_height);
++
++  web_contents_.reset(content::WebContents::Create(create_params));
++  web_contents_->SetDelegate(this);
++}
++
++} // namespace
++
++struct WebView::Private {
++  Evas_Object* root_window;
++  Evas_Object* view_box;
++  scoped_refptr<WebRuntimeContext> context;
++  scoped_ptr<WebContentsDelegateXWalk> webContentsDelegate;
++};
++
++// static
++WebView* WebView::Create(Evas_Object* root_window) {
++  return new WebView(root_window);
++}
++
++// static
++void WebView::CommandLineInit(int argc, char** argv) {
++  CommandLine::Init(argc, argv);
++}
++
++WebView::WebView(Evas_Object* root_window)
++    : private_(new Private) {
++  private_->root_window = root_window;
++  private_->context = WebRuntimeContext::current();
++  content::BrowserContext* browser_context =
++      private_->context->BrowserContext();
++  private_->webContentsDelegate.reset(
++      new WebContentsDelegateXWalk(browser_context));
++
++  private_->view_box = elm_box_add(private_->root_window);
++  content::WebContentsView* content_view =
++      private_->webContentsDelegate->WebContents()->GetView();
++  static_cast<content::WebContentsViewEfl*>(content_view)->
++      SetViewContainerBox(private_->view_box);
++}
++
++WebView::~WebView() {
++  evas_object_del(private_->view_box);
++}
++
++void WebView::Forward() {
++  private_->webContentsDelegate->WebContents()->GetController().GoForward();
++}
++
++void WebView::Back() {
++  private_->webContentsDelegate->WebContents()->GetController().GoBack();
++}
++
++Evas_Object* WebView::EvasObject() {
++  return private_->view_box;
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+new file mode 100644
+index 0000000..2d4b352
+--- /dev/null
++++ b/efl_webview/lib/webview.h
+@@ -0,0 +1,40 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIBWINDOW_H_
++#define EFL_WEBVIEW_LIBWINDOW_H_
++
++#include <Evas.h>
++
++#include "base/basictypes.h"
++#include "base/memory/scoped_ptr.h"
++
++namespace xwalk {
++
++class EAPI WebView {
++ public:
++  EAPI static WebView* Create(Evas_Object* root_window);
++  EAPI static void CommandLineInit(int argc, char** argv);
++
++  ~WebView();
++
++  EAPI Evas_Object* EvasObject();
++
++  EAPI void Forward();
++  EAPI void Back();
++
++ private:
++  explicit WebView(Evas_Object*);
++
++  struct Private;
++  scoped_ptr<Private> private_;
++
++  DISALLOW_COPY_AND_ASSIGN(WebView);
++};
++
++WebView* ToWebView(Evas_Object*);
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIBWINDOW_H_
+diff --git a/efl_webview/process/main.cc b/efl_webview/process/main.cc
+new file mode 100644
+index 0000000..27ba835
+--- /dev/null
++++ b/efl_webview/process/main.cc
+@@ -0,0 +1,10 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/process_main.h"
++
++int main(int argc, char **argv)
++{
++    return xwalk::ProcessMain(argc, argv);
++}
+-- 
+1.8.1.2
+
diff --git a/patchset/0006-Add-message_pump_xwalk-for-embedder.patch b/patchset/0006-Add-message_pump_xwalk-for-embedder.patch
new file mode 100644 (file)
index 0000000..7ac651d
--- /dev/null
@@ -0,0 +1,302 @@
+From 8bee019d38339e687bbdde6654c36193510c21b8 Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Wed, 3 Jul 2013 15:26:51 +0300
+Subject: [PATCH 06/33] Add message_pump_xwalk for embedder.
+
+This message pump does not have main loop. This message pump works with
+elm_run().
+
+After this patch, app can use content_api like common elm_object.
+
+How to build and run.
+
+make efl_webview_example
+./out/[Debug|Release]/efl_webview_example
+
+There are only two api classes:
+1. xwalk::WebView
+2. xwalk::ProcessMain() <- function
+
+TODO
+1. make elm_websomething using xwalk::WebView
+2. all xwalk changes get together into efl_webview/lib directory
+3. more stablize
+---
+ efl_webview/efl_webview.gyp                     |   2 +
+ efl_webview/lib/browser_context_xwalk.h         |   3 +-
+ efl_webview/lib/content_browser_client_xwalk.cc |   6 +-
+ efl_webview/lib/message_pump_xwalk.cc           | 119 ++++++++++++++++++++++++
+ efl_webview/lib/message_pump_xwalk.h            |  57 ++++++++++++
+ efl_webview/lib/web_runtime_context.cc          |   9 ++
+ 6 files changed, 193 insertions(+), 3 deletions(-)
+ create mode 100644 efl_webview/lib/message_pump_xwalk.cc
+ create mode 100644 efl_webview/lib/message_pump_xwalk.h
+
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index b4d25d3..3037aa2 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -53,6 +53,8 @@
+         'lib/content_browser_client_xwalk.cc',
+         'lib/content_browser_client_xwalk.h',
+         'lib/browser_context_xwalk.h',
++        'lib/message_pump_xwalk.cc',
++        'lib/message_pump_xwalk.h',
+         'lib/process_main.cc',
+         'lib/process_main.h',
+         'lib/web_runtime_context.cc',
+diff --git a/efl_webview/lib/browser_context_xwalk.h b/efl_webview/lib/browser_context_xwalk.h
+index 869fa82..0bd3cda 100644
+--- a/efl_webview/lib/browser_context_xwalk.h
++++ b/efl_webview/lib/browser_context_xwalk.h
+@@ -18,7 +18,8 @@ class BrowserContextXWalk : public content::ShellBrowserContext {
+   net::URLRequestContextGetter* CreateRequestContext(
+       content::ProtocolHandlerMap* protocol_handlers) {
+-    return content::ShellBrowserContext::CreateRequestContext(protocol_handlers);
++    return content::ShellBrowserContext::CreateRequestContext(
++        protocol_handlers);
+   }
+  private:
+diff --git a/efl_webview/lib/content_browser_client_xwalk.cc b/efl_webview/lib/content_browser_client_xwalk.cc
+index 7a14c99..b640320 100644
+--- a/efl_webview/lib/content_browser_client_xwalk.cc
++++ b/efl_webview/lib/content_browser_client_xwalk.cc
+@@ -53,8 +53,10 @@ content::BrowserMainParts *ContentBrowserClientXWalk::CreateBrowserMainParts(
+ net::URLRequestContextGetter* ContentBrowserClientXWalk::CreateRequestContext(
+     content::BrowserContext* content_browser_context,
+     content::ProtocolHandlerMap* protocol_handlers) {
+-  DCHECK(content_browser_context == WebRuntimeContext::current()->BrowserContext());
+-  return static_cast<BrowserContextXWalk*>(content_browser_context)->CreateRequestContext(protocol_handlers);
++  DCHECK(content_browser_context ==
++      WebRuntimeContext::current()->BrowserContext());
++  return static_cast<BrowserContextXWalk*>(content_browser_context)->
++      CreateRequestContext(protocol_handlers);
+ }
+ } // namespace xwalk
+diff --git a/efl_webview/lib/message_pump_xwalk.cc b/efl_webview/lib/message_pump_xwalk.cc
+new file mode 100644
+index 0000000..dd17582
+--- /dev/null
++++ b/efl_webview/lib/message_pump_xwalk.cc
+@@ -0,0 +1,119 @@
++// 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 "efl_webview/lib/message_pump_xwalk.h"
++
++#include <Ecore.h>
++#include <Ecore_X.h>
++
++#include "base/debug/trace_event.h"
++#include "base/logging.h"
++#include "base/posix/eintr_wrapper.h"
++#include "base/threading/platform_thread.h"
++
++namespace xwalk {
++
++namespace {
++
++const int ecorePipeMessageSize = 1;
++const char wakupEcorePipeMessage[] = "W";
++
++void WakeUpEvent(void* data, void*, unsigned int)
++{
++  static_cast<MessagePumpXWalk*>(data)->HandleDispatch();
++}
++
++}  // namespace
++
++struct MessagePumpXWalk::Private {
++  MessagePump::Delegate* delegate;
++
++  bool should_quit;
++
++  // This is the time when we need to do delayed work.
++  base::TimeTicks delayed_work_time;
++
++  // List of observers.
++  ObserverList<base::MessagePumpObserver> observers;
++
++  Ecore_Pipe* wakeup_pipe;
++};
++
++MessagePumpXWalk::MessagePumpXWalk()
++    : private_(new Private) {
++  private_->wakeup_pipe = ecore_pipe_add(WakeUpEvent, this);
++  private_->delegate = base::MessageLoopForUI::current();
++  private_->should_quit = false;
++}
++
++MessagePumpXWalk::~MessagePumpXWalk() {
++  ecore_pipe_del(private_->wakeup_pipe);
++}
++
++void MessagePumpXWalk::RunWithDispatcher(Delegate* delegate,
++    base::MessagePumpDispatcher* dispatcher) {
++  NOTREACHED();
++}
++
++void MessagePumpXWalk::HandleDispatch() {
++  // FIXME: dshwang does not have confidence about this implementation.
++  // Need to check by efl experts.
++  ecore_main_loop_iterate();
++
++  bool more_work_is_plausible = private_->delegate->DoWork();
++  if (private_->should_quit)
++    return;
++
++  more_work_is_plausible |=
++      private_->delegate->DoDelayedWork(&private_->delayed_work_time);
++  if (private_->should_quit)
++    return;
++
++  if (!more_work_is_plausible)
++    more_work_is_plausible |= private_->delegate->DoIdleWork();
++
++  if (more_work_is_plausible)
++    ScheduleWork();
++}
++
++void MessagePumpXWalk::AddObserver(base::MessagePumpObserver* observer) {
++  private_->observers.AddObserver(observer);
++}
++
++void MessagePumpXWalk::RemoveObserver(base::MessagePumpObserver* observer) {
++  private_->observers.RemoveObserver(observer);
++}
++
++void MessagePumpXWalk::Run(Delegate* delegate) {
++  NOTREACHED();
++}
++
++void MessagePumpXWalk::Quit() {
++  private_->should_quit = true;
++}
++
++void MessagePumpXWalk::ScheduleWork() {
++  // This can be called on any thread, so we don't want to touch any state
++  // variables as we would then need locks all over.  This ensures that if
++  // we are sleeping in a poll that we will wake up.
++  if (HANDLE_EINTR(ecore_pipe_write(private_->wakeup_pipe,
++                                    wakupEcorePipeMessage,
++                                    ecorePipeMessageSize)) != 1) {
++    NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
++  }
++}
++
++void MessagePumpXWalk::ScheduleDelayedWork(
++    const base::TimeTicks& delayed_work_time) {
++  // We need to wake up the loop in case the poll timeout needs to be
++  // adjusted.  This will cause us to try to do work, but that's ok.
++  private_->delayed_work_time = delayed_work_time;
++  ScheduleWork();
++}
++
++ObserverList<base::MessagePumpObserver>& MessagePumpXWalk::observers() {
++  return private_->observers;
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/message_pump_xwalk.h b/efl_webview/lib/message_pump_xwalk.h
+new file mode 100644
+index 0000000..b45c42f
+--- /dev/null
++++ b/efl_webview/lib/message_pump_xwalk.h
+@@ -0,0 +1,57 @@
++// 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 EFL_WEBVIEW_LIBMESSAGE_PUMP_XWALK_H_
++#define EFL_WEBVIEW_LIBMESSAGE_PUMP_XWALK_H_
++
++#include "base/base_export.h"
++#include "base/event_types.h"
++#include "base/memory/scoped_ptr.h"
++#include "base/message_pump.h"
++#include "base/message_pump_dispatcher.h"
++#include "base/message_pump_observer.h"
++#include "base/observer_list.h"
++#include "base/time.h"
++
++namespace xwalk {
++
++class MessagePumpXWalk : public base::MessagePump {
++public:
++  MessagePumpXWalk();
++
++  // Like MessagePump::Run, but events are routed through dispatcher.
++  virtual void RunWithDispatcher(Delegate* delegate,
++                                 base::MessagePumpDispatcher* dispatcher);
++
++  void HandleDispatch();
++
++  // Adds an Observer, which will start receiving notifications immediately.
++  void AddObserver(base::MessagePumpObserver* observer);
++
++  // Removes an Observer.  It is safe to call this method while an Observer is
++  // receiving a notification callback.
++  void RemoveObserver(base::MessagePumpObserver* observer);
++
++  // Overridden from MessagePump:
++  virtual void Run(Delegate* delegate) OVERRIDE;
++  virtual void Quit() OVERRIDE;
++  virtual void ScheduleWork() OVERRIDE;
++  virtual void ScheduleDelayedWork(
++      const base::TimeTicks& delayed_work_time) OVERRIDE;
++
++protected:
++  virtual ~MessagePumpXWalk();
++
++  ObserverList<base::MessagePumpObserver>& observers();
++
++private:
++  struct Private;
++  scoped_ptr<Private> private_;
++
++  DISALLOW_COPY_AND_ASSIGN(MessagePumpXWalk);
++};
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIBMESSAGE_PUMP_XWALK_H_
+diff --git a/efl_webview/lib/web_runtime_context.cc b/efl_webview/lib/web_runtime_context.cc
+index b2ad541..84613a8 100644
+--- a/efl_webview/lib/web_runtime_context.cc
++++ b/efl_webview/lib/web_runtime_context.cc
+@@ -29,6 +29,7 @@
+ #include "content/public/common/main_function_params.h"
+ #include "efl_webview/lib/browser_context_xwalk.h"
+ #include "efl_webview/lib/content_browser_client_xwalk.h"
++#include "efl_webview/lib/message_pump_xwalk.h"
+ namespace xwalk {
+@@ -66,12 +67,20 @@ void SubprocessPathInit() {
+       AppendSwitchPath(switches::kBrowserSubprocessPath, subprocess_path);
+ }
++base::MessagePump* MessagePumpFactory()
++{
++    return new MessagePumpXWalk;
++}
++
+ } // namespace
+ WebRuntimeContext::WebRuntimeContext() {
+   DCHECK(!g_context);
+   g_context = this;
++  // Inject MessagePumpFacotry for embedder.
++  base::MessageLoop::InitMessagePumpForUIFactory(MessagePumpFactory);
++
+   static content::ContentMainRunner *runner = 0;
+   if (!runner) {
+     runner = content::ContentMainRunner::Create();
+-- 
+1.8.1.2
+
diff --git a/patchset/0007-XWalk-must-set-ContentClient-for-user-agent.patch b/patchset/0007-XWalk-must-set-ContentClient-for-user-agent.patch
new file mode 100644 (file)
index 0000000..46ad184
--- /dev/null
@@ -0,0 +1,289 @@
+From ea4d75808eb04875c233f6a2acda23a98f09ad76 Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Fri, 5 Jul 2013 14:32:19 +0300
+Subject: [PATCH 07/33] XWalk must set ContentClient for user agent.
+
+This patch is base on Alex's finding.
+content_client_xwalk is copied for xwalk project.
+Render process must know user agent.
+The solution is easy. ProcessMain uses ContentMainDelegateXWalk.
+---
+ efl_webview/DEPS                               |  2 +
+ efl_webview/efl_webview.gyp                    |  4 ++
+ efl_webview/lib/content_client_xwalk.cc        | 52 ++++++++++++++++++++++++++
+ efl_webview/lib/content_client_xwalk.h         | 36 ++++++++++++++++++
+ efl_webview/lib/content_main_delegate_xwalk.cc | 29 ++++++++++++++
+ efl_webview/lib/content_main_delegate_xwalk.h  | 33 ++++++++++++++++
+ efl_webview/lib/process_main.cc                |  4 +-
+ efl_webview/lib/web_runtime_context.cc         | 18 +--------
+ 8 files changed, 160 insertions(+), 18 deletions(-)
+ create mode 100644 efl_webview/lib/content_client_xwalk.cc
+ create mode 100644 efl_webview/lib/content_client_xwalk.h
+ create mode 100644 efl_webview/lib/content_main_delegate_xwalk.cc
+ create mode 100644 efl_webview/lib/content_main_delegate_xwalk.h
+
+diff --git a/efl_webview/DEPS b/efl_webview/DEPS
+index dd8d329..1b41ffd 100644
+--- a/efl_webview/DEPS
++++ b/efl_webview/DEPS
+@@ -1,4 +1,6 @@
+ include_rules = [
+   "+content",
+   "+net",
++  "+ui",
++  "+webkit",
+ ]
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index 3037aa2..f6b959f 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -52,6 +52,10 @@
+       'sources': [
+         'lib/content_browser_client_xwalk.cc',
+         'lib/content_browser_client_xwalk.h',
++        'lib/content_client_xwalk.cc',
++        'lib/content_client_xwalk.h',
++        'lib/content_main_delegate_xwalk.cc',
++        'lib/content_main_delegate_xwalk.h',
+         'lib/browser_context_xwalk.h',
+         'lib/message_pump_xwalk.cc',
+         'lib/message_pump_xwalk.h',
+diff --git a/efl_webview/lib/content_client_xwalk.cc b/efl_webview/lib/content_client_xwalk.cc
+new file mode 100644
+index 0000000..0549d6b
+--- /dev/null
++++ b/efl_webview/lib/content_client_xwalk.cc
+@@ -0,0 +1,52 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/content_client_xwalk.h"
++
++#include "base/command_line.h"
++#include "base/string_piece.h"
++#include "base/utf_string_conversions.h"
++#include "content/public/common/content_switches.h"
++#include "ui/base/l10n/l10n_util.h"
++#include "ui/base/resource/resource_bundle.h"
++#include "webkit/user_agent/user_agent_util.h"
++
++namespace xwalk {
++
++ContentClientXWalk::ContentClientXWalk() {
++}
++
++ContentClientXWalk::~ContentClientXWalk() {
++}
++
++std::string ContentClientXWalk::GetUserAgent() const {
++  // TODO(hmin): Define user agent for xwalk.
++  std::string product = "Chrome/0.0.1";
++  CommandLine* command_line = CommandLine::ForCurrentProcess();
++  if (command_line->HasSwitch(switches::kUseMobileUserAgent))
++    product += " Mobile";
++  return webkit_glue::BuildUserAgentFromProduct(product);
++}
++
++string16 ContentClientXWalk::GetLocalizedString(int message_id) const {
++  return l10n_util::GetStringUTF16(message_id);
++}
++
++base::StringPiece ContentClientXWalk::GetDataResource(
++    int resource_id,
++    ui::ScaleFactor scale_factor) const {
++  return ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
++      resource_id, scale_factor);
++}
++
++base::RefCountedStaticMemory* ContentClientXWalk::GetDataResourceBytes(
++    int resource_id) const {
++  return ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id);
++}
++
++gfx::Image& ContentClientXWalk::GetNativeImageNamed(int resource_id) const {
++  return ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/content_client_xwalk.h b/efl_webview/lib/content_client_xwalk.h
+new file mode 100644
+index 0000000..0d88260
+--- /dev/null
++++ b/efl_webview/lib/content_client_xwalk.h
+@@ -0,0 +1,36 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_CONTENT_CLIENT_XWALK_H_
++#define EFL_WEBVIEW_LIB_CONTENT_CLIENT_XWALK_H_
++
++#include <string>
++#include <vector>
++
++#include "base/compiler_specific.h"
++#include "content/public/common/content_client.h"
++
++namespace xwalk {
++
++class ContentClientXWalk : public content::ContentClient {
++ public:
++  ContentClientXWalk();
++  virtual ~ContentClientXWalk();
++
++  virtual std::string GetUserAgent() const OVERRIDE;
++  virtual string16 GetLocalizedString(int message_id) const OVERRIDE;
++  virtual base::StringPiece GetDataResource(
++      int resource_id,
++      ui::ScaleFactor scale_factor) const OVERRIDE;
++  virtual base::RefCountedStaticMemory* GetDataResourceBytes(
++      int resource_id) const OVERRIDE;
++  virtual gfx::Image& GetNativeImageNamed(int resource_id) const OVERRIDE;
++
++ private:
++  DISALLOW_COPY_AND_ASSIGN(ContentClientXWalk);
++};
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIB_CONTENT_CLIENT_XWALK_H_
+diff --git a/efl_webview/lib/content_main_delegate_xwalk.cc b/efl_webview/lib/content_main_delegate_xwalk.cc
+new file mode 100644
+index 0000000..526dd8a
+--- /dev/null
++++ b/efl_webview/lib/content_main_delegate_xwalk.cc
+@@ -0,0 +1,29 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/content_main_delegate_xwalk.h"
++
++#include "efl_webview/lib/content_browser_client_xwalk.h"
++#include "ui/base/resource/resource_bundle.h"
++
++namespace xwalk {
++
++ContentMainDelegateXWalk::ContentMainDelegateXWalk() { }
++
++void ContentMainDelegateXWalk::PreSandboxStartup() {
++  ui::ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL);
++}
++
++bool ContentMainDelegateXWalk::BasicStartupComplete(int* exit_code) {
++  content::SetContentClient(&content_client_);
++  return false;
++}
++
++content::ContentBrowserClient*
++    ContentMainDelegateXWalk::CreateContentBrowserClient() {
++  browser_client_.reset(new ContentBrowserClientXWalk);
++  return browser_client_.get();
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/content_main_delegate_xwalk.h b/efl_webview/lib/content_main_delegate_xwalk.h
+new file mode 100644
+index 0000000..850ee61
+--- /dev/null
++++ b/efl_webview/lib/content_main_delegate_xwalk.h
+@@ -0,0 +1,33 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_CONTENT_MAIN_DELEGATE_XWALK_H_
++#define EFL_WEBVIEW_LIB_CONTENT_MAIN_DELEGATE_XWALK_H_
++
++#include "base/compiler_specific.h"
++#include "base/memory/scoped_ptr.h"
++#include "content/public/app/content_main_delegate.h"
++#include "efl_webview/lib/content_browser_client_xwalk.h"
++#include "efl_webview/lib/content_client_xwalk.h"
++
++namespace xwalk {
++
++class ContentMainDelegateXWalk : public content::ContentMainDelegate {
++ public:
++  ContentMainDelegateXWalk();
++
++  virtual void PreSandboxStartup() OVERRIDE;
++  virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
++  virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
++
++ private:
++  scoped_ptr<ContentBrowserClientXWalk> browser_client_;
++  ContentClientXWalk content_client_;
++
++  DISALLOW_COPY_AND_ASSIGN(ContentMainDelegateXWalk);
++};
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIB_CONTENT_MAIN_DELEGATE_XWALK_H_
+diff --git a/efl_webview/lib/process_main.cc b/efl_webview/lib/process_main.cc
+index 132b35c..5f1e4e44 100644
+--- a/efl_webview/lib/process_main.cc
++++ b/efl_webview/lib/process_main.cc
+@@ -8,6 +8,7 @@
+ #include "base/logging.h"
+ #include "content/public/app/content_main.h"
+ #include "content/public/common/content_switches.h"
++#include "efl_webview/lib/content_main_delegate_xwalk.h"
+ namespace xwalk {
+@@ -18,7 +19,8 @@ int ProcessMain(int argc, char** argv) {
+       command_line.GetSwitchValueASCII(switches::kProcessType);
+   CHECK(process_type != "");
+-  return content::ContentMain(argc, const_cast<const char**>(argv), 0);
++  ContentMainDelegateXWalk delegate;
++  return content::ContentMain(argc, const_cast<const char**>(argv), &delegate);
+ }
+ }  // namespace xwalk
+diff --git a/efl_webview/lib/web_runtime_context.cc b/efl_webview/lib/web_runtime_context.cc
+index 84613a8..005a6d2 100644
+--- a/efl_webview/lib/web_runtime_context.cc
++++ b/efl_webview/lib/web_runtime_context.cc
+@@ -22,34 +22,18 @@
+ #include "base/base_paths.h"
+ #include "base/command_line.h"
+ #include "base/path_service.h"
+-#include "content/public/app/content_main_delegate.h"
+ #include "content/public/app/content_main_runner.h"
+ #include "content/public/browser/browser_main_runner.h"
+ #include "content/public/common/content_switches.h"
+ #include "content/public/common/main_function_params.h"
+ #include "efl_webview/lib/browser_context_xwalk.h"
+-#include "efl_webview/lib/content_browser_client_xwalk.h"
++#include "efl_webview/lib/content_main_delegate_xwalk.h"
+ #include "efl_webview/lib/message_pump_xwalk.h"
+ namespace xwalk {
+ namespace {
+-class ContentMainDelegateXWalk : public content::ContentMainDelegate {
+- public:
+-  ContentMainDelegateXWalk() { }
+-
+-  content::ContentBrowserClient* CreateContentBrowserClient()   {
+-    browser_client_.reset(new ContentBrowserClientXWalk);
+-    return browser_client_.get();
+-  }
+-
+- private:
+-  scoped_ptr<ContentBrowserClientXWalk> browser_client_;
+-
+-  DISALLOW_COPY_AND_ASSIGN(ContentMainDelegateXWalk);
+-};
+-
+ WebRuntimeContext* g_context = 0;
+ // TODO: it should be passed via build system.
+ const char g_sub_process_name[] = "efl_process";
+-- 
+1.8.1.2
+
diff --git a/patchset/0008-Add-reload-button.patch b/patchset/0008-Add-reload-button.patch
new file mode 100644 (file)
index 0000000..457a77c
--- /dev/null
@@ -0,0 +1,171 @@
+From e8dc8c58037f1c9cfd5678150c77e9113bf8754a Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Thu, 4 Jul 2013 15:12:47 +0300
+Subject: [PATCH 08/33] Add reload button.
+
+Load url that command line indicates.
+Add reload button.
+There are two purposes.
+1. show how to add API.
+2. check load correctly, because it is hard to check forward and back button due to lack of url field.
+---
+ efl_webview/examples/main.cc | 18 ++++++++++++++++++
+ efl_webview/lib/webview.cc   | 39 +++++++++++++++++++++++++++++++++++++++
+ efl_webview/lib/webview.h    |  3 +++
+ 3 files changed, 60 insertions(+)
+
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index ee610fb..f69ad43 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -28,6 +28,14 @@ on_forward_button_clicked(void *user_data, Evas_Object *forward_button, void *ev
+   webview->Forward();
+ }
++static void
++on_reload_button_clicked(void *user_data,
++                         Evas_Object *forward_button, void *event_info)
++{
++  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
++  webview->Reload();
++}
++
+ static void window_create()
+ {
+   /* Create window */
+@@ -65,6 +73,14 @@ static void window_create()
+   elm_box_pack_end(horizontal_layout, forward_button);
+   evas_object_show(forward_button);
++  /* Create Reload button */
++  Evas_Object* reload_button = elm_button_add(elm_window);
++  elm_object_text_set(reload_button, "RELOAD");
++  evas_object_size_hint_weight_set(reload_button, 0.0, EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(reload_button, 0.0, 0.5);
++  elm_box_pack_end(horizontal_layout, reload_button);
++  evas_object_show(reload_button);
++
+   /* Create WebView */
+   xwalk::WebView* webview_object = xwalk::WebView::Create(elm_window);
+   Evas_Object* webview = webview_object->EvasObject();
+@@ -78,6 +94,8 @@ static void window_create()
+                                  on_back_button_clicked, webview_object);
+   evas_object_smart_callback_add(forward_button, "clicked",
+                                  on_forward_button_clicked, webview_object);
++  evas_object_smart_callback_add(reload_button, "clicked",
++                                 on_reload_button_clicked, webview_object);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index 510f452..33b00de 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -6,10 +6,13 @@
+ #include <Elementary.h>
+ #include "base/command_line.h"
++#include "base/file_util.h"
++#include "base/files/file_path.h"
+ #include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/browser/web_contents.h"
+ #include "content/public/browser/web_contents_delegate.h"
+ #include "efl_webview/lib/web_runtime_context.h"
++#include "net/base/net_util.h"
+ namespace xwalk {
+@@ -44,8 +47,11 @@ struct WebView::Private {
+   Evas_Object* view_box;
+   scoped_refptr<WebRuntimeContext> context;
+   scoped_ptr<WebContentsDelegateXWalk> webContentsDelegate;
++  static GURL s_startup_url;
+ };
++GURL WebView::Private::s_startup_url = GURL();
++
+ // static
+ WebView* WebView::Create(Evas_Object* root_window) {
+   return new WebView(root_window);
+@@ -54,10 +60,27 @@ WebView* WebView::Create(Evas_Object* root_window) {
+ // static
+ void WebView::CommandLineInit(int argc, char** argv) {
+   CommandLine::Init(argc, argv);
++
++  CommandLine* command_line = CommandLine::ForCurrentProcess();
++  const CommandLine::StringVector& args = command_line->GetArgs();
++
++  if (args.empty())
++    return;
++
++  GURL url(args[0]);
++  if (!(url.is_valid() && url.has_scheme()))
++    url = net::FilePathToFileURL(base::FilePath(args[0]));
++
++  WebView::Private::s_startup_url = GURL(url);
+ }
+ WebView::WebView(Evas_Object* root_window)
+     : private_(new Private) {
++  {
++    if (!WebView::Private::s_startup_url.is_valid())
++      WebView::Private::s_startup_url = GURL("about:blank");
++  }
++
+   private_->root_window = root_window;
+   private_->context = WebRuntimeContext::current();
+   content::BrowserContext* browser_context =
+@@ -70,6 +93,8 @@ WebView::WebView(Evas_Object* root_window)
+       private_->webContentsDelegate->WebContents()->GetView();
+   static_cast<content::WebContentsViewEfl*>(content_view)->
+       SetViewContainerBox(private_->view_box);
++
++  LoadURL(WebView::Private::s_startup_url);
+ }
+ WebView::~WebView() {
+@@ -84,6 +109,20 @@ void WebView::Back() {
+   private_->webContentsDelegate->WebContents()->GetController().GoBack();
+ }
++void WebView::Reload() {
++  private_->webContentsDelegate->WebContents()->GetController().Reload(false);
++}
++
++void WebView::LoadURL(const GURL& url) {
++  content::NavigationController::LoadURLParams params(url);
++  params.transition_type = content::PageTransitionFromInt(
++      content::PAGE_TRANSITION_TYPED |
++      content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
++  private_->webContentsDelegate->WebContents()->
++      GetController().LoadURLWithParams(params);
++  private_->webContentsDelegate->WebContents()->GetView()->Focus();
++}
++
+ Evas_Object* WebView::EvasObject() {
+   return private_->view_box;
+ }
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index 2d4b352..ca1757e 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -9,6 +9,7 @@
+ #include "base/basictypes.h"
+ #include "base/memory/scoped_ptr.h"
++#include "googleurl/src/gurl.h"
+ namespace xwalk {
+@@ -23,6 +24,8 @@ class EAPI WebView {
+   EAPI void Forward();
+   EAPI void Back();
++  EAPI void Reload();
++  EAPI void LoadURL(const GURL&);
+  private:
+   explicit WebView(Evas_Object*);
+-- 
+1.8.1.2
+
diff --git a/patchset/0009-Implement-focus-handling-of-delegate.patch b/patchset/0009-Implement-focus-handling-of-delegate.patch
new file mode 100644 (file)
index 0000000..a31fb2c
--- /dev/null
@@ -0,0 +1,590 @@
+From c1f83116854209a14f7c7fde0b6851297b584c3b Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Mon, 22 Jul 2013 19:49:15 +0300
+Subject: [PATCH 09/33] Implement focus handling of delegate.
+
+There are two important delegate functions that allow embedder control focus.
+1. WebContentsViewDelegate::Focus() : time to focus in web contents widget.
+2. WebContentsDelegate::TakeFocus() : time to focus out web contents widget and
+focus in next widget in toolkit framework.
+---
+ .../renderer_host/render_widget_host_view_efl.cc   | 27 +++++++++----
+ .../browser/web_contents/web_contents_view_efl.cc  | 10 +++--
+ .../browser/web_contents/web_contents_view_efl.h   |  1 +
+ .../public/browser/web_contents_view_delegate.h    |  2 +
+ content/shell/DEPS                                 |  3 ++
+ content/shell/shell.cc                             |  6 +++
+ content/shell/shell.h                              |  2 +
+ content/shell/shell_efl.cc                         | 10 +++++
+ content/shell/shell_web_contents_view_delegate.h   |  1 +
+ .../shell/shell_web_contents_view_delegate_efl.cc  |  9 +++++
+ efl_webview/efl_webview.gyp                        |  4 ++
+ efl_webview/examples/main.cc                       |  4 +-
+ efl_webview/lib/content_browser_client_xwalk.cc    |  8 ++++
+ efl_webview/lib/content_browser_client_xwalk.h     |  2 +
+ efl_webview/lib/web_contents_delegate_xwalk.cc     | 36 +++++++++++++++++
+ efl_webview/lib/web_contents_delegate_xwalk.h      | 35 ++++++++++++++++
+ .../lib/web_contents_view_delegate_xwalk.cc        | 40 +++++++++++++++++++
+ efl_webview/lib/web_contents_view_delegate_xwalk.h | 40 +++++++++++++++++++
+ efl_webview/lib/webview.cc                         | 46 ++++++----------------
+ 19 files changed, 241 insertions(+), 45 deletions(-)
+ create mode 100644 efl_webview/lib/web_contents_delegate_xwalk.cc
+ create mode 100644 efl_webview/lib/web_contents_delegate_xwalk.h
+ create mode 100644 efl_webview/lib/web_contents_view_delegate_xwalk.cc
+ create mode 100644 efl_webview/lib/web_contents_view_delegate_xwalk.h
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 9858418..22b1967 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -131,10 +131,19 @@ void RenderWidgetHostViewEfl::PreserveWindowKeyUp(Evas_Event_Key_Up* key_up) {
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowFocusIn() {
++  ShowCurrentCursor();
++  if (!host_)
++      return;
++
++  host_->GotFocus();
++  host_->SetActive(true);
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowFocusOut() {
+-//  root_window_host_delegate_->OnHostLostMouseGrab();
++  if (host_ && !IsShowingContextMenu()) {
++    host_->SetActive(false);
++    host_->Blur();
++  }
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowShow() {
+@@ -148,11 +157,15 @@ void RenderWidgetHostViewEfl::PreserveWindowMove(const gfx::Point& origin) {
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowResize(const gfx::Size& size) {
+-  SetSize(size);
++  if (!host_)
++    return;
++    SetSize(size);
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowRepaint(const gfx::Rect& damage_rect) {
+-  Paint(damage_rect);
++  if (!host_)
++    return;
++    Paint(damage_rect);
+ }
+ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
+@@ -169,12 +182,10 @@ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
+ void RenderWidgetHostViewEfl::InitAsChild(
+     gfx::NativeView parent_view) {
+-  Evas_Object* elm_box = reinterpret_cast<Evas_Object*>(parent_view);
+-  Evas* evas = evas_object_evas_get(elm_box);
+-  preserve_window_ = gfx::PreserveWindow::Create(this, evas);
++  preserve_window_ = gfx::PreserveWindow::Create(this, evas_object_evas_get(parent_view));
+   evas_object_size_hint_align_set(preserve_window_->SmartObject(), EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_box_pack_end(elm_box, preserve_window_->SmartObject());
++  elm_box_pack_end(parent_view, preserve_window_->SmartObject());
+   evas_object_show(preserve_window_->SmartObject());
+   compositing_surface_ = elm_win_xwindow_get(preserve_window_->EvasWindow());
+ }
+@@ -241,7 +252,7 @@ void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
+ }
+ gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
+-  return reinterpret_cast<gfx::NativeView>(preserve_window_->SmartObject());
++  return preserve_window_->SmartObject();
+ }
+ gfx::NativeViewId RenderWidgetHostViewEfl::GetNativeViewId() const {
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index ccdfbf3..3885d0b 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -70,7 +70,9 @@ void WebContentsViewEfl::OnTabCrashed(base::TerminationStatus status,
+ }
+ void WebContentsViewEfl::Focus() {
+-  // TODO: Focus.
++  if (delegate_) {
++    delegate_->Focus();
++  }
+ }
+ void WebContentsViewEfl::SetInitialFocus() {
+@@ -110,7 +112,7 @@ RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
+   RenderWidgetHostView* view =
+       RenderWidgetHostView::CreateViewForWidget(render_widget_host);
+-  view->InitAsChild(reinterpret_cast<gfx::NativeView>(view_container_box_));
++  view->InitAsChild(view_container_box_);
+   if (render_widget_host->IsRenderView()) {
+     RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
+     if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
+@@ -158,7 +160,9 @@ void WebContentsViewEfl::GotFocus() {
+ // This is called when the renderer asks us to take focus back (i.e., it has
+ // iterated past the last focusable element on the page).
+ void WebContentsViewEfl::TakeFocus(bool reverse) {
+-  /* TODO: Assign Focus to EFL evas_object */
++  if (!web_contents_->GetDelegate())
++    return;
++  web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse);
+ }
+ void WebContentsViewEfl::UpdateDragDest(RenderViewHost* host) {
+diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
+index 3c6d2f6..e481009 100644
+--- a/content/browser/web_contents/web_contents_view_efl.h
++++ b/content/browser/web_contents/web_contents_view_efl.h
+@@ -81,6 +81,7 @@ class CONTENT_EXPORT WebContentsViewEfl
+   virtual void TakeFocus(bool reverse) OVERRIDE;
+   void SetViewContainerBox(Evas_Object* container_box) { view_container_box_ = container_box; }
++  Evas_Object* ViewContainerBox() { return view_container_box_; }
+  private:
+   void UpdateDragDest(RenderViewHost* new_host);
+diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h
+index 605582b..aec9701 100644
+--- a/content/public/browser/web_contents_view_delegate.h
++++ b/content/public/browser/web_contents_view_delegate.h
+@@ -81,6 +81,8 @@ class CONTENT_EXPORT WebContentsViewDelegate {
+   virtual NSObject<RenderWidgetHostViewMacDelegate>*
+       CreateRenderWidgetHostViewDelegate(
+           RenderWidgetHost* render_widget_host) = 0;
++#elif defined(TOOLKIT_EFL)
++  virtual void Focus() = 0;
+ #endif
+ };
+diff --git a/content/shell/DEPS b/content/shell/DEPS
+index 64bcfea..08bdc07 100644
+--- a/content/shell/DEPS
++++ b/content/shell/DEPS
+@@ -8,6 +8,9 @@ include_rules = [
+   # content's public API.
+   "+content/public",
++  # content/shell/shell_web_contents_view_delegate_efl.cc illegally include "content/browser/web_contents/web_contents_view_efl.h"
++  "+content/browser",
++
+   # The content_shell is an embedder so it must work with resource bundles.
+   "+ui/base/l10n",
+   "+ui/base/resource",
+diff --git a/content/shell/shell.cc b/content/shell/shell.cc
+index 5eac7af..9e6576e 100644
+--- a/content/shell/shell.cc
++++ b/content/shell/shell.cc
+@@ -309,6 +309,12 @@ void Shell::DeactivateContents(WebContents* contents) {
+   contents->GetRenderViewHost()->Blur();
+ }
++#if !defined(TOOLKIT_EFL)
++bool Shell::TakeFocus(WebContents* source, bool reverse) {
++  return false;
++}
++#endif
++
+ void Shell::Observe(int type,
+                     const NotificationSource& source,
+                     const NotificationDetails& details) {
+diff --git a/content/shell/shell.h b/content/shell/shell.h
+index e58bb42..2d9ba10 100644
+--- a/content/shell/shell.h
++++ b/content/shell/shell.h
+@@ -144,6 +144,8 @@ class Shell : public WebContentsDelegate,
+   virtual void RendererUnresponsive(WebContents* source) OVERRIDE;
+   virtual void ActivateContents(WebContents* contents) OVERRIDE;
+   virtual void DeactivateContents(WebContents* contents) OVERRIDE;
++  virtual bool TakeFocus(content::WebContents* source,
++                         bool reverse) OVERRIDE;
+  private:
+   enum UIControl {
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+index 557424e..e4ec4e5 100644
+--- a/content/shell/shell_efl.cc
++++ b/content/shell/shell_efl.cc
+@@ -105,4 +105,14 @@ void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
+   delete shell;
+ }
++bool Shell::TakeFocus(WebContents* source, bool reverse) {
++  DCHECK(source == web_contents_.get());
++  WebContentsView* content_view = web_contents_->GetView();
++  Evas_Object* view_box =
++      static_cast<WebContentsViewEfl*>(content_view)->ViewContainerBox();
++  elm_object_focus_next(view_box,
++                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
++  return true;
++}
++
+ }  // namespace content
+diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
+index 283f37f..8352438 100644
+--- a/content/shell/shell_web_contents_view_delegate.h
++++ b/content/shell/shell_web_contents_view_delegate.h
+@@ -26,6 +26,7 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+   virtual void ShowContextMenu(const ContextMenuParams& params,
+                                ContextMenuSourceType type) OVERRIDE;
+   virtual WebDragDestDelegate* GetDragDestDelegate() OVERRIDE;
++  virtual void Focus() OVERRIDE;
+ #if defined(TOOLKIT_GTK)
+   virtual void Initialize(GtkWidget* expanded_container,
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+index 18498f3..60aaa16 100644
+--- a/content/shell/shell_web_contents_view_delegate_efl.cc
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -4,7 +4,9 @@
+ #include "content/shell/shell_web_contents_view_delegate.h"
++#include <Elementary.h>
+ #include "base/command_line.h"
++#include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/browser/render_process_host.h"
+ #include "content/public/browser/render_view_host.h"
+ #include "content/public/browser/render_widget_host_view.h"
+@@ -48,4 +50,11 @@ WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
+   return NULL;
+ }
++void ShellWebContentsViewDelegate::Focus() {
++  WebContentsView* content_view = web_contents_->GetView();
++  Evas_Object* view_box =
++      static_cast<WebContentsViewEfl*>(content_view)->ViewContainerBox();
++  elm_object_focus_set(view_box, EINA_TRUE);
++}
++
+ }  // namespace content
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index f6b959f..f49badd 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -61,6 +61,10 @@
+         'lib/message_pump_xwalk.h',
+         'lib/process_main.cc',
+         'lib/process_main.h',
++        'lib/web_contents_delegate_xwalk.cc',
++        'lib/web_contents_delegate_xwalk.h',
++        'lib/web_contents_view_delegate_xwalk.cc',
++        'lib/web_contents_view_delegate_xwalk.h',
+         'lib/web_runtime_context.cc',
+         'lib/web_runtime_context.h',
+         'lib/webview.cc',
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index f69ad43..a41c986 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -41,6 +41,8 @@ static void window_create()
+   /* Create window */
+   Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window", APP_NAME);
+   elm_win_autodel_set(elm_window, EINA_TRUE);
++  elm_object_focus_allow_set(elm_window, EINA_TRUE);
++  elm_win_focus_highlight_enabled_set(elm_window, EINA_TRUE);
+   /* Create vertical layout */
+   Evas_Object* vertical_layout = elm_box_add(elm_window);
+@@ -87,7 +89,7 @@ static void window_create()
+   evas_object_size_hint_weight_set(webview, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(webview, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vertical_layout, webview);
+-  evas_object_focus_set(webview, EINA_TRUE);
++  elm_object_focus_set(webview, EINA_TRUE);
+   evas_object_show(webview);
+   evas_object_smart_callback_add(back_button, "clicked",
+diff --git a/efl_webview/lib/content_browser_client_xwalk.cc b/efl_webview/lib/content_browser_client_xwalk.cc
+index b640320..cc2269e 100644
+--- a/efl_webview/lib/content_browser_client_xwalk.cc
++++ b/efl_webview/lib/content_browser_client_xwalk.cc
+@@ -5,8 +5,10 @@
+ #include "efl_webview/lib/content_browser_client_xwalk.h"
+ #include "content/public/browser/browser_main_parts.h"
++#include "content/public/browser/web_contents.h"
+ #include "content/public/common/main_function_params.h"
+ #include "efl_webview/lib/browser_context_xwalk.h"
++#include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
+ #include "efl_webview/lib/web_runtime_context.h"
+ namespace xwalk {
+@@ -59,4 +61,10 @@ net::URLRequestContextGetter* ContentBrowserClientXWalk::CreateRequestContext(
+       CreateRequestContext(protocol_handlers);
+ }
++content::WebContentsViewDelegate*
++    ContentBrowserClientXWalk::GetWebContentsViewDelegate(
++    content::WebContents* web_contents) {
++  return new WebContentsViewDelegateXWalk(web_contents);
++}
++
+ } // namespace xwalk
+diff --git a/efl_webview/lib/content_browser_client_xwalk.h b/efl_webview/lib/content_browser_client_xwalk.h
+index c5c235d..a8ff6ae 100644
+--- a/efl_webview/lib/content_browser_client_xwalk.h
++++ b/efl_webview/lib/content_browser_client_xwalk.h
+@@ -19,6 +19,8 @@ class ContentBrowserClientXWalk : public content::ContentBrowserClient {
+   virtual net::URLRequestContextGetter* CreateRequestContext(
+       content::BrowserContext* browser_context,
+       content::ProtocolHandlerMap* protocol_handlers) OVERRIDE;
++  virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate(
++      content::WebContents* web_contents) OVERRIDE;
+  private:
+   DISALLOW_COPY_AND_ASSIGN(ContentBrowserClientXWalk);
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.cc b/efl_webview/lib/web_contents_delegate_xwalk.cc
+new file mode 100644
+index 0000000..a6cb3a3
+--- /dev/null
++++ b/efl_webview/lib/web_contents_delegate_xwalk.cc
+@@ -0,0 +1,36 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/web_contents_delegate_xwalk.h"
++
++#include <Elementary.h>
++#include "content/public/browser/web_contents.h"
++#include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
++
++namespace xwalk {
++
++namespace {
++const int g_window_width = 800;
++const int g_window_height = 600;
++} // namespace
++
++WebContentsDelegateXWalk::WebContentsDelegateXWalk(
++    content::BrowserContext* browser_context, Evas_Object* view_box)
++    : view_box_(view_box)
++{
++  content::WebContents::CreateParams create_params(browser_context, 0);
++  create_params.initial_size = gfx::Size(g_window_width, g_window_height);
++
++  web_contents_.reset(content::WebContents::Create(create_params));
++  web_contents_->SetDelegate(this);
++}
++
++bool WebContentsDelegateXWalk::TakeFocus(
++    content::WebContents* source, bool reverse) {
++  elm_object_focus_next(view_box_,
++                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
++  return true;
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.h b/efl_webview/lib/web_contents_delegate_xwalk.h
+new file mode 100644
+index 0000000..182d2e8
+--- /dev/null
++++ b/efl_webview/lib/web_contents_delegate_xwalk.h
+@@ -0,0 +1,35 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_WEB_CONTENTS_DELEGATE_XWALK_H_
++#define EFL_WEBVIEW_LIB_WEB_CONTENTS_DELEGATE_XWALK_H_
++
++#include <Evas.h>
++
++#include "base/memory/scoped_ptr.h"
++#include "content/public/browser/web_contents_delegate.h"
++
++namespace content {
++class WebContentsViewDelegate;
++}
++
++namespace xwalk {
++
++class WebContentsDelegateXWalk : public content::WebContentsDelegate
++{
++ public:
++  WebContentsDelegateXWalk(content::BrowserContext*, Evas_Object*);
++  virtual bool TakeFocus(content::WebContents* source,
++                         bool reverse) OVERRIDE;
++
++  content::WebContents* WebContents() { return web_contents_.get(); }
++
++ private:
++  Evas_Object* view_box_;
++  scoped_ptr<content::WebContents> web_contents_;
++};
++
++} // namespace xwalk
++
++#endif // EFL_WEBVIEW_LIB_WEB_CONTENTS_DELEGATE_XWALK_H_
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.cc b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+new file mode 100644
+index 0000000..40b59f7
+--- /dev/null
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+@@ -0,0 +1,40 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
++
++#include <Elementary.h>
++
++namespace xwalk {
++
++WebContentsViewDelegateXWalk::WebContentsViewDelegateXWalk(
++    content::WebContents* web_contents)
++    : web_contents_(web_contents)
++    , view_box_(NULL) {
++}
++
++WebContentsViewDelegateXWalk::~WebContentsViewDelegateXWalk() {
++}
++
++void WebContentsViewDelegateXWalk::Focus() {
++  if (!view_box_)
++    return;
++  elm_object_focus_set(view_box_, EINA_TRUE);
++}
++
++void WebContentsViewDelegateXWalk::ShowContextMenu(
++    const content::ContextMenuParams& params,
++    content::ContextMenuSourceType type) {
++}
++
++content::WebDragDestDelegate*
++    WebContentsViewDelegateXWalk::GetDragDestDelegate() {
++  return NULL;
++}
++
++void WebContentsViewDelegateXWalk::SetViewContainerBox(Evas_Object* view_box) {
++  view_box_ = view_box;
++}
++
++}  // namespace xwalk
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.h b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+new file mode 100644
+index 0000000..d5df813
+--- /dev/null
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+@@ -0,0 +1,40 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_WEB_CONTENTS_VIEW_DELEGATE_XWALK_H_
++#define EFL_WEBVIEW_LIB_WEB_CONTENTS_VIEW_DELEGATE_XWALK_H_
++
++#include "base/compiler_specific.h"
++#include "content/public/browser/web_contents_view_delegate.h"
++
++namespace content {
++class WebContents;
++}
++
++namespace xwalk {
++
++class WebContentsViewDelegateXWalk : public content::WebContentsViewDelegate {
++ public:
++  explicit WebContentsViewDelegateXWalk(content::WebContents*);
++  virtual ~WebContentsViewDelegateXWalk();
++
++  // Overridden from WebContentsViewDelegate:
++  virtual void ShowContextMenu(
++      const content::ContextMenuParams& params,
++      content::ContextMenuSourceType type) OVERRIDE;
++  virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE;
++  virtual void Focus() OVERRIDE;
++
++  void SetViewContainerBox(Evas_Object*);
++
++ private:
++  content::WebContents* web_contents_;
++  Evas_Object* view_box_;
++
++  DISALLOW_COPY_AND_ASSIGN(WebContentsViewDelegateXWalk);
++};
++
++} // namespace xwalk
++
++#endif // EFL_WEBVIEW_LIB_WEB_CONTENTS_VIEW_DELEGATE_XWALK_H_
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index 33b00de..061d30c 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -10,38 +10,13 @@
+ #include "base/files/file_path.h"
+ #include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/browser/web_contents.h"
+-#include "content/public/browser/web_contents_delegate.h"
++#include "efl_webview/lib/web_contents_delegate_xwalk.h"
++#include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
+ #include "efl_webview/lib/web_runtime_context.h"
+ #include "net/base/net_util.h"
+ namespace xwalk {
+-namespace {
+-const int g_window_width = 800;
+-const int g_window_height = 600;
+-
+-class WebContentsDelegateXWalk : public content::WebContentsDelegate
+-{
+- public:
+-  explicit WebContentsDelegateXWalk(content::BrowserContext*);
+-  content::WebContents* WebContents() { return web_contents_.get(); }
+-
+- private:
+-  scoped_ptr<content::WebContents> web_contents_;
+-};
+-
+-WebContentsDelegateXWalk::WebContentsDelegateXWalk(
+-    content::BrowserContext* browser_context)
+-{
+-  content::WebContents::CreateParams create_params(browser_context, 0);
+-  create_params.initial_size = gfx::Size(g_window_width, g_window_height);
+-
+-  web_contents_.reset(content::WebContents::Create(create_params));
+-  web_contents_->SetDelegate(this);
+-}
+-
+-} // namespace
+-
+ struct WebView::Private {
+   Evas_Object* root_window;
+   Evas_Object* view_box;
+@@ -82,16 +57,21 @@ WebView::WebView(Evas_Object* root_window)
+   }
+   private_->root_window = root_window;
++  private_->view_box = elm_box_add(private_->root_window);
++  elm_object_focus_allow_set(private_->view_box, EINA_TRUE);
++
+   private_->context = WebRuntimeContext::current();
+   content::BrowserContext* browser_context =
+       private_->context->BrowserContext();
+   private_->webContentsDelegate.reset(
+-      new WebContentsDelegateXWalk(browser_context));
+-
+-  private_->view_box = elm_box_add(private_->root_window);
+-  content::WebContentsView* content_view =
+-      private_->webContentsDelegate->WebContents()->GetView();
+-  static_cast<content::WebContentsViewEfl*>(content_view)->
++      new WebContentsDelegateXWalk(browser_context, private_->view_box));
++
++  content::WebContentsViewEfl* content_view =
++      static_cast<content::WebContentsViewEfl*>(private_->
++          webContentsDelegate->WebContents()->GetView());
++  // FIXME: Don't pass elm_box to WebContentsViewEfl. Need focus handling of PreserveWindow evas object here.
++  content_view->SetViewContainerBox(private_->view_box);
++  static_cast<WebContentsViewDelegateXWalk*>(content_view->delegate())->
+       SetViewContainerBox(private_->view_box);
+   LoadURL(WebView::Private::s_startup_url);
+-- 
+1.8.1.2
+
diff --git a/patchset/0010-Introducing-C-API-for-EFL-Web-View.patch b/patchset/0010-Introducing-C-API-for-EFL-Web-View.patch
new file mode 100644 (file)
index 0000000..6c6ca87
--- /dev/null
@@ -0,0 +1,560 @@
+From 1fe3191d93a63d2279747388e237907439287698 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Wed, 10 Jul 2013 17:23:24 +0300
+Subject: [PATCH 10/33] Introducing C API for EFL Web View.
+
+Wrap xwalk initialization
+Introduce EinaSharedString
+Introduce xwalk_view_url api
+---
+ base/base.gyp                          |  2 ++
+ base/strings/efl/eina_shared_string.cc | 53 ++++++++++++++++++++++++++++++
+ base/strings/efl/eina_shared_string.h  | 52 +++++++++++++++++++++++++++++
+ efl_webview/efl_webview.gyp            |  4 +++
+ efl_webview/examples/main.cc           | 39 +++++++++++-----------
+ efl_webview/lib/webview.cc             | 41 +++++++++++++++++++++--
+ efl_webview/lib/webview.h              | 24 +++++++++-----
+ efl_webview/public/xwalk_main.cc       | 10 ++++++
+ efl_webview/public/xwalk_main.h        | 19 +++++++++++
+ efl_webview/public/xwalk_view.cc       | 60 ++++++++++++++++++++++++++++++++++
+ efl_webview/public/xwalk_view.h        | 29 ++++++++++++++++
+ 11 files changed, 303 insertions(+), 30 deletions(-)
+ create mode 100644 base/strings/efl/eina_shared_string.cc
+ create mode 100644 base/strings/efl/eina_shared_string.h
+ create mode 100644 efl_webview/public/xwalk_main.cc
+ create mode 100644 efl_webview/public/xwalk_main.h
+ create mode 100644 efl_webview/public/xwalk_view.cc
+ create mode 100644 efl_webview/public/xwalk_view.h
+
+diff --git a/base/base.gyp b/base/base.gyp
+index b9e7e36..6b80e40 100644
+--- a/base/base.gyp
++++ b/base/base.gyp
+@@ -87,6 +87,8 @@
+             '../build/linux/system.gyp:efl',
+           ],
+           'sources': [
++            'strings/efl/eina_shared_string.cc',
++            'strings/efl/eina_shared_string.h',
+             'message_pump_efl.cc',
+             'message_pump_efl.h',
+           ],
+diff --git a/base/strings/efl/eina_shared_string.cc b/base/strings/efl/eina_shared_string.cc
+new file mode 100644
+index 0000000..48b4862
+--- /dev/null
++++ b/base/strings/efl/eina_shared_string.cc
+@@ -0,0 +1,53 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "base/strings/efl/eina_shared_string.h"
++
++EinaSharedString::EinaSharedString(const EinaSharedString& other)
++  : string_(eina_stringshare_ref(other.string_)) {
++}
++
++EinaSharedString::EinaSharedString(const char* str)
++  : string_(eina_stringshare_add(str)) {
++}
++
++EinaSharedString::EinaSharedString(const std::string& str)
++  : string_(eina_stringshare_add(str.c_str())) {
++}
++
++EinaSharedString::~EinaSharedString() {
++  if (string_)
++    eina_stringshare_del(string_);
++}
++
++EinaSharedString& EinaSharedString::operator=(const EinaSharedString& other) {
++  if (this != &other) {
++    if (string_)
++      eina_stringshare_del(string_);
++    string_ = eina_stringshare_ref(other.string_);
++  }
++  return *this;
++}
++
++EinaSharedString& EinaSharedString::operator=(const char* str) {
++  eina_stringshare_replace(&string_, str);
++  return *this;
++}
++
++bool EinaSharedString::operator==(const char* str) const {
++  return (!str || !string_) ? (str == string_) : !strcmp(string_, str);
++}
++
++EinaSharedString EinaSharedString::Adopt(Eina_Stringshare* string) {
++  EinaSharedString sharedString;
++  sharedString.string_ = static_cast<const char*>(string);
++  return sharedString;
++}
++
++Eina_Stringshare* EinaSharedString::LeakString() {
++  Eina_Stringshare* sharedString = string_;
++  string_ = 0;
++
++  return sharedString;
++}
+diff --git a/base/strings/efl/eina_shared_string.h b/base/strings/efl/eina_shared_string.h
+new file mode 100644
+index 0000000..6fc0aee
+--- /dev/null
++++ b/base/strings/efl/eina_shared_string.h
+@@ -0,0 +1,52 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EINA_SHARED_STRING_H_
++#define EINA_SHARED_STRING_H_
++
++#include "base/base_export.h"
++
++#include <Eina.h>
++
++#include <string>
++
++namespace base {
++
++class BASE_EXPORT EinaSharedString {
++public:
++  EinaSharedString() : string_(0) { }
++  EinaSharedString(const EinaSharedString& other);
++  EinaSharedString(const char* str);
++  explicit EinaSharedString(const std::string&);
++
++  ~EinaSharedString();
++
++  Eina_Stringshare* LeakString();
++
++  EinaSharedString& operator=(const EinaSharedString& other);
++  EinaSharedString& operator=(const char* str);
++
++  bool operator==(const EinaSharedString& other) const { return string_ == other.string_; }
++  bool operator!=(const EinaSharedString& other) const { return !(*this == other); }
++
++  bool operator==(const char* str) const;
++  bool operator!=(const char* str) const { return !(*this == str); }
++
++  operator const char* () const { return string_; }
++
++  bool IsNull() const { return !string_; }
++
++  size_t Length() const { return string_ ? static_cast<size_t>(eina_stringshare_strlen(string_)) : 0; }
++
++  static EinaSharedString Adopt(Eina_Stringshare*);
++
++private:
++  const char* string_;
++};
++
++} // namespace base
++
++using base::EinaSharedString;
++
++#endif // EINA_SHARED_STRING_H_
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index f49badd..c71eb7b 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -69,6 +69,10 @@
+         'lib/web_runtime_context.h',
+         'lib/webview.cc',
+         'lib/webview.h',
++        'public/xwalk_view.cc',
++        'public/xwalk_view.h',
++        'public/xwalk_main.cc',
++        'public/xwalk_main.h',
+       ],
+       'conditions': [
+         ['OS=="linux"', {
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index a41c986..db3a6dc 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -8,6 +8,8 @@
+ #include "efl_webview/lib/process_main.h"
+ #include "efl_webview/lib/webview.h"
++#include "efl_webview/public/xwalk_main.h"
++#include "efl_webview/public/xwalk_view.h"
+ static const char APP_NAME[] = "EFL WebView Example";
+@@ -17,26 +19,23 @@ static int window_height = 600;
+ static void
+ on_back_button_clicked(void *user_data, Evas_Object *back_button, void *event_info)
+ {
+-  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
+-  webview->Back();
++  xwalk_view_back((Evas_Object*)user_data);
+ }
+ static void
+ on_forward_button_clicked(void *user_data, Evas_Object *forward_button, void *event_info)
+ {
+-  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
+-  webview->Forward();
++  xwalk_view_forward((Evas_Object*)user_data);
+ }
+ static void
+ on_reload_button_clicked(void *user_data,
+                          Evas_Object *forward_button, void *event_info)
+ {
+-  xwalk::WebView* webview = static_cast<xwalk::WebView*>(user_data);
+-  webview->Reload();
++  xwalk_view_reload((Evas_Object*)user_data);
+ }
+-static void window_create()
++static void window_create(int argc)
+ {
+   /* Create window */
+   Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window", APP_NAME);
+@@ -84,36 +83,38 @@ static void window_create()
+   evas_object_show(reload_button);
+   /* Create WebView */
+-  xwalk::WebView* webview_object = xwalk::WebView::Create(elm_window);
+-  Evas_Object* webview = webview_object->EvasObject();
+-  evas_object_size_hint_weight_set(webview, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(webview, EVAS_HINT_FILL, EVAS_HINT_FILL);
+-  elm_box_pack_end(vertical_layout, webview);
+-  elm_object_focus_set(webview, EINA_TRUE);
+-  evas_object_show(webview);
++  Evas_Object* web_view = xwalk_view_add(elm_window);
++  evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(web_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
++  elm_box_pack_end(vertical_layout, web_view);
++  elm_object_focus_set(web_view, EINA_TRUE);
++  evas_object_show(web_view);
+   evas_object_smart_callback_add(back_button, "clicked",
+-                                 on_back_button_clicked, webview_object);
++                                 on_back_button_clicked, web_view);
+   evas_object_smart_callback_add(forward_button, "clicked",
+-                                 on_forward_button_clicked, webview_object);
++                                 on_forward_button_clicked, web_view);
+   evas_object_smart_callback_add(reload_button, "clicked",
+-                                 on_reload_button_clicked, webview_object);
++                                 on_reload_button_clicked, web_view);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
++
++  if (argc <= 1)
++    xwalk_view_url_set(web_view, "http://google.com");
+ }
+ int main(int argc, char *argv[])
+ {
+   // FIXME: Handle chrome command line and url.
+   // It is needed only in development stage.
+-  xwalk::WebView::CommandLineInit(argc, argv);
++  xwalk_init(argc, argv);
+   elm_init(argc, argv);
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+-  window_create();
++  window_create(argc);
+   elm_run();
+   elm_shutdown();
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index 061d30c..61ecb96 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -5,6 +5,9 @@
+ #include "efl_webview/lib/webview.h"
+ #include <Elementary.h>
++
++#include <map>
++
+ #include "base/command_line.h"
+ #include "base/file_util.h"
+ #include "base/files/file_path.h"
+@@ -15,6 +18,18 @@
+ #include "efl_webview/lib/web_runtime_context.h"
+ #include "net/base/net_util.h"
++namespace {
++
++typedef std::map<const Evas_Object*, xwalk::WebView*> EvasWebViewMap;
++
++inline EvasWebViewMap& EvasObjectToWebViewMap() {
++// FIXME: Temporary solution until web view has its own smart class.
++  static EvasWebViewMap map;
++  return map;
++}
++
++}  // namespace
++
+ namespace xwalk {
+ struct WebView::Private {
+@@ -58,6 +73,10 @@ WebView::WebView(Evas_Object* root_window)
+   private_->root_window = root_window;
+   private_->view_box = elm_box_add(private_->root_window);
++  // FIXME: In future this has to be a separate Smart Class representing web view.
++  // 'this' should be set as smart_data->priv
++  EvasObjectToWebViewMap()[private_->view_box] = this;
++
+   elm_object_focus_allow_set(private_->view_box, EINA_TRUE);
+   private_->context = WebRuntimeContext::current();
+@@ -78,14 +97,24 @@ WebView::WebView(Evas_Object* root_window)
+ }
+ WebView::~WebView() {
++// FIXME : And by the way who will invoke it?
++  EvasObjectToWebViewMap().erase(private_->view_box);
+   evas_object_del(private_->view_box);
+ }
+-void WebView::Forward() {
++bool WebView::CanGoBack() const {
++  return private_->webContentsDelegate->WebContents()->GetController().CanGoBack();
++}
++
++bool WebView::CanGoForward() const {
++  return private_->webContentsDelegate->WebContents()->GetController().CanGoForward();
++}
++
++void WebView::GoForward() {
+   private_->webContentsDelegate->WebContents()->GetController().GoForward();
+ }
+-void WebView::Back() {
++void WebView::GoBack() {
+   private_->webContentsDelegate->WebContents()->GetController().GoBack();
+ }
+@@ -94,6 +123,7 @@ void WebView::Reload() {
+ }
+ void WebView::LoadURL(const GURL& url) {
++  url_ = EinaSharedString(url.spec());
+   content::NavigationController::LoadURLParams params(url);
+   params.transition_type = content::PageTransitionFromInt(
+       content::PAGE_TRANSITION_TYPED |
+@@ -107,4 +137,11 @@ Evas_Object* WebView::EvasObject() {
+   return private_->view_box;
+ }
++WebView* ToWebView(const Evas_Object* evas_object) {
++  EvasWebViewMap::iterator found = EvasObjectToWebViewMap().find(evas_object);
++  if (found != EvasObjectToWebViewMap().end())
++    return found->second;
++  return 0;
++}
++
+ }  // namespace xwalk
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index ca1757e..ae4f98f 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -2,13 +2,14 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+-#ifndef EFL_WEBVIEW_LIBWINDOW_H_
+-#define EFL_WEBVIEW_LIBWINDOW_H_
++#ifndef EFL_WEBVIEW_LIB_WEBVIEW_H_
++#define EFL_WEBVIEW_LIB_WEBVIEW_H_
+ #include <Evas.h>
+ #include "base/basictypes.h"
+ #include "base/memory/scoped_ptr.h"
++#include "base/strings/efl/eina_shared_string.h"
+ #include "googleurl/src/gurl.h"
+ namespace xwalk {
+@@ -22,22 +23,27 @@ class EAPI WebView {
+   EAPI Evas_Object* EvasObject();
+-  EAPI void Forward();
+-  EAPI void Back();
+-  EAPI void Reload();
+-  EAPI void LoadURL(const GURL&);
++  bool CanGoBack() const;
++  bool CanGoForward() const;
++  void GoForward();
++  void GoBack();
++  void Reload();
++  void LoadURL(const GURL&);
++
++  const char* url() const { return url_; }
+  private:
+-  explicit WebView(Evas_Object*);
++  explicit WebView(Evas_Object* root_window);
+   struct Private;
+   scoped_ptr<Private> private_;
++  EinaSharedString url_;
+   DISALLOW_COPY_AND_ASSIGN(WebView);
+ };
+-WebView* ToWebView(Evas_Object*);
++WebView* ToWebView(const Evas_Object*);
+ }  // namespace xwalk
+-#endif  // EFL_WEBVIEW_LIBWINDOW_H_
++#endif  // EFL_WEBVIEW_LIB_WEBVIEW_H_
+diff --git a/efl_webview/public/xwalk_main.cc b/efl_webview/public/xwalk_main.cc
+new file mode 100644
+index 0000000..218c55d
+--- /dev/null
++++ b/efl_webview/public/xwalk_main.cc
+@@ -0,0 +1,10 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/public/xwalk_main.h"
++#include "efl_webview/lib/webview.h"
++
++void xwalk_init(int argc, char *argv[]) {
++  xwalk::WebView::CommandLineInit(argc, argv);
++}
+diff --git a/efl_webview/public/xwalk_main.h b/efl_webview/public/xwalk_main.h
+new file mode 100644
+index 0000000..b6c2f83
+--- /dev/null
++++ b/efl_webview/public/xwalk_main.h
+@@ -0,0 +1,19 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_PUBLIC_XWALK_MAIN_H_
++#define EFL_WEBVIEW_PUBLIC_XWALK_MAIN_H_
++
++#include <Evas.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++EAPI void xwalk_init(int argc, char *argv[]);
++
++#ifdef __cplusplus
++}
++#endif
++#endif  // EFL_WEBVIEW_PUBLIC_XWALK_MAIN_H_
+diff --git a/efl_webview/public/xwalk_view.cc b/efl_webview/public/xwalk_view.cc
+new file mode 100644
+index 0000000..b000143
+--- /dev/null
++++ b/efl_webview/public/xwalk_view.cc
+@@ -0,0 +1,60 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include "efl_webview/public/xwalk_view.h"
++#include "efl_webview/lib/webview.h"
++
++using namespace xwalk;
++
++#define XWALK_VIEW_GET_IMPL_OR_RETURN(xwalk_view, impl, ...)         \
++  WebView* impl = ToWebView(xwalk_view);                             \
++  do {                                                               \
++    if (!impl) {                                                     \
++      EINA_LOG_CRIT("no private data for object %p", xwalk_view);    \
++      return __VA_ARGS__;                                            \
++    }                                                                \
++  } while (0)
++
++
++Evas_Object* xwalk_view_add(Evas_Object* root_window) {
++  return WebView::Create(root_window)->EvasObject();
++}
++
++Eina_Bool xwalk_view_url_set(Evas_Object* evas_object, const char* url) {
++  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
++  EINA_SAFETY_ON_NULL_RETURN_VAL(url, false);
++
++  impl->LoadURL(GURL(url));
++  return true;
++}
++
++const char* xwalk_view_url_get(const Evas_Object* evas_object) {
++  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, "");
++  return impl->url();
++}
++
++Eina_Bool xwalk_view_reload(Evas_Object* evas_object) {
++  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
++  impl->Reload();
++
++  return true;
++}
++
++Eina_Bool xwalk_view_back(Evas_Object* evas_object) {
++  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
++  if (impl->CanGoBack()) {
++    impl->GoBack();
++    return true;
++  }
++  return false;
++}
++
++Eina_Bool xwalk_view_forward(Evas_Object* evas_object) {
++  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
++  if (impl->CanGoForward()) {
++    impl->GoForward();
++    return true;
++  }
++  return false;
++}
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+new file mode 100644
+index 0000000..a4c85d58
+--- /dev/null
++++ b/efl_webview/public/xwalk_view.h
+@@ -0,0 +1,29 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_PUBLIC_XWALK_VIEW_H_
++#define EFL_WEBVIEW_PUBLIC_XWALK_VIEW_H_
++
++#include <Evas.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++EAPI Evas_Object *xwalk_view_add(Evas_Object *root_window);
++
++EAPI Eina_Bool xwalk_view_url_set(Evas_Object *obj, const char *url);
++
++EAPI const char *xwalk_view_url_get(const Evas_Object *obj);
++
++EAPI Eina_Bool xwalk_view_reload(Evas_Object *obj);
++
++EAPI Eina_Bool xwalk_view_back(Evas_Object *obj);
++
++EAPI Eina_Bool xwalk_view_forward(Evas_Object *obj);
++
++#ifdef __cplusplus
++}
++#endif
++#endif  // EFL_WEBVIEW_PUBLIC_XWALK_VIEW_H_
+-- 
+1.8.1.2
+
diff --git a/patchset/0011-Cleanup-example.-Call-Xlib-directly.-Add-URL-entry.patch b/patchset/0011-Cleanup-example.-Call-Xlib-directly.-Add-URL-entry.patch
new file mode 100644 (file)
index 0000000..ba87c36
--- /dev/null
@@ -0,0 +1,369 @@
+From 4de7656080a7f132dd17194362ae37e9b2e764bd Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Tue, 30 Jul 2013 12:15:45 +0300
+Subject: [PATCH 11/33] Cleanup example. Call Xlib directly. Add URL entry.
+
+example: Do not enable focus highlighting.
+Default focus highlighting works in a very silly and confusing way in
+Elementary: it just puts a sad emoticon over the widget that has focus.
+
+example: Do not call xwalk_view_url_set() by default.
+Doing this would always try to load the same hard-coded URL regardless of
+the URL passed on the command line.
+
+Add url entry field
+
+Call Xlib directly instead of hacking around elm_win.
+
+Use Ecore_X and Xlib calls instead of elm_win_add(.., ELM_WIN_DOCK) and
+ecore_x_window_reparent().
+The previous approach was very hackish and relied on EWMH (or NetWM hints)
+to work as expected in order to create a separate X Window that is embedded
+into the main one we export to API users.
+We now use ecore_x_window_new() directly and just relay events to the parent
+X Window with XChangeWindowAttributes(), and it works much better.
+Integration with Wayland is still a big unknown, both due to the way Wayland
+works and the way we implement PreserveWindow in EFL.
+
+Rename PreserveWindow::EvasWindow() to EmbeddedXWindow().
+EvasWindow() stopped making much sense after 5da472c, so use a name that
+better conveys what we are returning.
+---
+ .../renderer_host/render_widget_host_view_efl.cc   | 20 +++++-
+ efl_webview/examples/main.cc                       | 72 ++++++++++++++--------
+ ui/gfx/preserve_window_efl.cc                      | 48 +++++++--------
+ ui/gfx/preserve_window_efl.h                       |  3 +-
+ 4 files changed, 88 insertions(+), 55 deletions(-)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 22b1967..1e12159 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -103,14 +103,32 @@ RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* mouse_down) {
++  // The coordinates must be relative to the view, not the root window.
++  int view_x, view_y;
++  evas_object_geometry_get(preserve_window_->SmartObject(),
++                           &view_x, &view_y, NULL, NULL);
++  mouse_down->canvas.x = mouse_down->canvas.x - view_x;
++  mouse_down->canvas.y = mouse_down->canvas.y - view_y;
+   host_->ForwardMouseEvent(content::mouseEvent(mouse_down));
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowMouseUp(Evas_Event_Mouse_Up* mouse_up) {
++  // The coordinates must be relative to the view, not the root window.
++  int view_x, view_y;
++  evas_object_geometry_get(preserve_window_->SmartObject(),
++                           &view_x, &view_y, NULL, NULL);
++  mouse_up->canvas.x = mouse_up->canvas.x - view_x;
++  mouse_up->canvas.y = mouse_up->canvas.y - view_y;
+   host_->ForwardMouseEvent(content::mouseEvent(mouse_up));
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowMouseMove(Evas_Event_Mouse_Move* mouse_move) {
++  // The coordinates must be relative to the view, not the root window.
++  int view_x, view_y;
++  evas_object_geometry_get(preserve_window_->SmartObject(),
++                           &view_x, &view_y, NULL, NULL);
++  mouse_move->cur.canvas.x = mouse_move->cur.canvas.x - view_x;
++  mouse_move->cur.canvas.y = mouse_move->cur.canvas.y - view_y;
+   host_->ForwardMouseEvent(content::mouseEvent(mouse_move));
+ }
+@@ -187,7 +205,7 @@ void RenderWidgetHostViewEfl::InitAsChild(
+   evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_pack_end(parent_view, preserve_window_->SmartObject());
+   evas_object_show(preserve_window_->SmartObject());
+-  compositing_surface_ = elm_win_xwindow_get(preserve_window_->EvasWindow());
++  compositing_surface_ = preserve_window_->EmbeddedXWindow();
+ }
+ void RenderWidgetHostViewEfl::InitAsPopup(
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index db3a6dc..6dac4e8 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -17,40 +17,52 @@ static int window_width = 800;
+ static int window_height = 600;
+ static void
+-on_back_button_clicked(void *user_data, Evas_Object *back_button, void *event_info)
++on_back_button_clicked(void *user_data, Evas_Object *back_button,
++                       void *event_info)
+ {
+   xwalk_view_back((Evas_Object*)user_data);
+ }
+ static void
+-on_forward_button_clicked(void *user_data, Evas_Object *forward_button, void *event_info)
++on_forward_button_clicked(void *user_data, Evas_Object *forward_button,
++                          void *event_info)
+ {
+   xwalk_view_forward((Evas_Object*)user_data);
+ }
+ static void
+-on_reload_button_clicked(void *user_data,
+-                         Evas_Object *forward_button, void *event_info)
++on_reload_button_clicked(void *user_data, Evas_Object *forward_button,
++                         void *event_info)
+ {
+   xwalk_view_reload((Evas_Object*)user_data);
+ }
+-static void window_create(int argc)
++static void
++on_url_entry_activated(void *user_data, Evas_Object *url_entry,
++                       void *event_info)
+ {
+-  /* Create window */
+-  Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window", APP_NAME);
++    const char* url = elm_entry_entry_get(url_entry);
++    xwalk_view_url_set((Evas_Object*)user_data, url);
++}
++
++
++static void window_create()
++{
++  /* Create elementary window */
++  Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window",
++                                                      APP_NAME);
+   elm_win_autodel_set(elm_window, EINA_TRUE);
+   elm_object_focus_allow_set(elm_window, EINA_TRUE);
+-  elm_win_focus_highlight_enabled_set(elm_window, EINA_TRUE);
+-  /* Create vertical layout */
++  /* Create vertical layout that holds navigation bar and webview area */
+   Evas_Object* vertical_layout = elm_box_add(elm_window);
+-  elm_box_padding_set(vertical_layout, 0, 2);
+-  evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  elm_box_padding_set(vertical_layout, 0, 4);
++  evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(elm_window, vertical_layout);
+   evas_object_show(vertical_layout);
+-  /* Create horizontal layout for top bar */
++  /* Create horizontal layout for navigation bar */
+   Evas_Object* horizontal_layout = elm_box_add(elm_window);
+   elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
+   evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
+@@ -58,33 +70,42 @@ static void window_create(int argc)
+   elm_box_pack_end(vertical_layout, horizontal_layout);
+   evas_object_show(horizontal_layout);
+-  /* Create Back button */
++  /* Create back button */
+   Evas_Object* back_button = elm_button_add(elm_window);
+   elm_object_text_set(back_button, "BACK");
+-  evas_object_size_hint_weight_set(back_button, 0.0, EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(back_button, 0.0, 0.5);
+   elm_box_pack_end(horizontal_layout, back_button);
+   evas_object_show(back_button);
+-  /* Create Forward button */
++  /* Create forward button */
+   Evas_Object* forward_button = elm_button_add(elm_window);
+   elm_object_text_set(forward_button, "FORWARD");
+-  evas_object_size_hint_weight_set(forward_button, 0.0, EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(forward_button, 0.0, 0.5);
+   elm_box_pack_end(horizontal_layout, forward_button);
+   evas_object_show(forward_button);
+-  /* Create Reload button */
++  /* Create reload button */
+   Evas_Object* reload_button = elm_button_add(elm_window);
+   elm_object_text_set(reload_button, "RELOAD");
+-  evas_object_size_hint_weight_set(reload_button, 0.0, EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(reload_button, 0.0, 0.5);
+   elm_box_pack_end(horizontal_layout, reload_button);
+   evas_object_show(reload_button);
++  /* Create url entry widget */
++  Evas_Object* url_entry = elm_entry_add(elm_window);
++  elm_entry_single_line_set(url_entry, EINA_TRUE);
++  elm_entry_scrollable_set(url_entry, EINA_TRUE);
++  elm_entry_cnp_mode_set(url_entry, ELM_CNP_MODE_PLAINTEXT);
++  elm_entry_scrollbar_policy_set(url_entry, ELM_SCROLLER_POLICY_OFF,
++                                 ELM_SCROLLER_POLICY_OFF);
++  elm_entry_text_style_user_push(url_entry, "DEFAULT='font_size=16'");
++  evas_object_size_hint_weight_set(url_entry, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(url_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
++  elm_box_pack_end(horizontal_layout, url_entry);
++  evas_object_show(url_entry);
++
+   /* Create WebView */
+   Evas_Object* web_view = xwalk_view_add(elm_window);
+-  evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(web_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(vertical_layout, web_view);
+   elm_object_focus_set(web_view, EINA_TRUE);
+@@ -96,12 +117,11 @@ static void window_create(int argc)
+                                  on_forward_button_clicked, web_view);
+   evas_object_smart_callback_add(reload_button, "clicked",
+                                  on_reload_button_clicked, web_view);
++  evas_object_smart_callback_add(url_entry, "activated",
++                                 on_url_entry_activated, web_view);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+-
+-  if (argc <= 1)
+-    xwalk_view_url_set(web_view, "http://google.com");
+ }
+ int main(int argc, char *argv[])
+@@ -114,7 +134,7 @@ int main(int argc, char *argv[])
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+-  window_create(argc);
++  window_create();
+   elm_run();
+   elm_shutdown();
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index 4601099..9c3fe3a 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -8,6 +8,7 @@
+ #include <Ecore_Evas.h>
+ #include <Ecore_X.h>
+ #include <Elementary.h>
++#include <X11/Xlib.h>
+ #include "base/logging.h"
+ #include "ui/gfx/point.h"
+@@ -51,11 +52,9 @@ const char* PreserveWindowSmartEvent(PreserveWindowSmartEventType type) {
+ }
+ struct PreserveWindowData {
+-  Evas_Object_Smart_Clipped_Data base;
+-  Evas_Object* window_;
+-  // FIXME (alexshalamov): It is dummy to receive input events.
+-  // We must find proper event handling way.
+-  Evas_Object* background_;
++   Evas_Object_Smart_Clipped_Data base;
++   Ecore_X_Window window_;
++   Evas_Object* background_;
+ };
+ bool IsPreserveWindowEvasObject(const Evas_Object* evas_object) {
+@@ -111,44 +110,40 @@ void evas_smart_preserve_window_smart_add(Evas_Object* o) {
+     evas_object_smart_data_set(o, smart_data);
+   }
+-  int x, y, w, h = 0;
+-  evas_object_geometry_get(o, &x, &y, &w, &h);
++  smart_data->window_ = ecore_x_window_new(elm_win_xwindow_get(o), 0, 0, 1, 1);
+-  smart_data->window_ = elm_win_add(o, "preserve-window", ELM_WIN_DOCK);
+-  evas_object_resize(smart_data->window_, w, h);
+-  evas_object_show(smart_data->window_);
++  // Do not listen to any events in this new window, otherwise they will not be
++  // propagated to the parent X window (the one which is actually interested in
++  // them).
++  XSetWindowAttributes attributes;
++  attributes.event_mask = NoEventMask;
++  XChangeWindowAttributes(static_cast<Display*>(ecore_x_display_get()),
++                          smart_data->window_, CWEventMask, &attributes);
+-  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
+-  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
+-  ecore_x_window_reparent(x_window, root_x_window, x, y);
+-
+-  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(smart_data->window_));
++  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(o));
+   evas_object_color_set(smart_data->background_, 0, 0, 0, 0);
+   evas_object_size_hint_weight_set(smart_data->background_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_win_resize_object_add(smart_data->window_, smart_data->background_);
+   evas_object_focus_set(smart_data->background_, EINA_TRUE);
+   evas_smart_preserve_window_parent_sc->add(o);
+ }
+ void evas_smart_preserve_window_smart_del(Evas_Object* o) {
+   PreserveWindowData* smart_data = ToSmartData(o);
+-  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
+-  ecore_x_window_reparent(x_window, 0 /* default root window */, 0 /* x */, 0 /* y */);
+   evas_object_del(smart_data->background_);
+-  evas_object_del(smart_data->window_);
++  ecore_x_window_free(smart_data->window_);
+   evas_smart_preserve_window_parent_sc->del(o);
+ }
+ void evas_smart_preserve_window_smart_show(Evas_Object* o) {
+   PreserveWindowData* smart_data = ToSmartData(o);
+-  evas_object_show(smart_data->window_);
++  ecore_x_window_show(smart_data->window_);
+   evas_object_show(smart_data->background_);
+   evas_smart_preserve_window_parent_sc->show(o);
+ }
+ void evas_smart_preserve_window_smart_hide(Evas_Object* o) {
+   PreserveWindowData* smart_data = ToSmartData(o);
+-  evas_object_hide(smart_data->window_);
++  ecore_x_window_hide(smart_data->window_);
+   evas_object_hide(smart_data->background_);
+   evas_smart_preserve_window_parent_sc->hide(o);
+ }
+@@ -162,9 +157,8 @@ void evas_smart_preserve_window_smart_move(Evas_Object* o,
+     return;
+   PreserveWindowData* smart_data = ToSmartData(o);
+-  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
+-  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
+-  ecore_x_window_reparent(x_window, root_x_window, x, y);
++  ecore_x_window_move(smart_data->window_, x, y);
++  evas_object_move(smart_data->background_, x, y);
+   int position[2] = {x, y};
+   evas_object_smart_callback_call(
+@@ -183,7 +177,8 @@ void evas_smart_preserve_window_smart_resize(Evas_Object* o,
+     return;
+   PreserveWindowData* smart_data = ToSmartData(o);
+-  evas_object_resize(smart_data->window_, w, h);
++  ecore_x_window_resize(smart_data->window_, w, h);
++  evas_object_resize(smart_data->background_, w, h);
+   int size[2] = {w, h};
+   evas_object_smart_callback_call(
+@@ -412,8 +407,7 @@ PreserveWindow::~PreserveWindow() {
+   evas_object_del(smart_object_);
+ }
+-
+-Evas_Object* PreserveWindow::EvasWindow() {
++gfx::PluginWindowHandle PreserveWindow::EmbeddedXWindow() {
+   PreserveWindowData* smart_data = ToSmartData(smart_object_);
+   return smart_data->window_;
+ }
+diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
+index 56a0b78..1097072 100644
+--- a/ui/gfx/preserve_window_efl.h
++++ b/ui/gfx/preserve_window_efl.h
+@@ -11,6 +11,7 @@
+ #include "base/memory/scoped_ptr.h"
+ #include "ui/base/ui_export.h"
+ #include "ui/gfx/preserve_window_delegate_efl.h"
++#include "ui/gfx/native_widget_types.h"
+ namespace gfx {
+@@ -21,7 +22,7 @@ class UI_EXPORT PreserveWindow {
+   ~PreserveWindow();
+   Evas_Object* SmartObject() const { return smart_object_; }
+-  Evas_Object* EvasWindow();
++  PluginWindowHandle EmbeddedXWindow();
+  private:
+   PreserveWindow(PreserveWindowDelegate*, Evas*);
+-- 
+1.8.1.2
+
diff --git a/patchset/0012-WebView-re-factoring-no-dep-to-elm-memory-management.patch b/patchset/0012-WebView-re-factoring-no-dep-to-elm-memory-management.patch
new file mode 100644 (file)
index 0000000..fc1d1b4
--- /dev/null
@@ -0,0 +1,489 @@
+From 4acef7c4becad5d74cbdfda9045d968a8628eb27 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Thu, 1 Aug 2013 13:57:05 +0300
+Subject: [PATCH 12/33] WebView re-factoring: no dep to elm, memory management.
+
+---
+ .../renderer_host/render_widget_host_view_efl.cc   |   4 +-
+ .../renderer_host/render_widget_host_view_efl.h    |   2 +-
+ efl_webview/examples/main.cc                       |   2 +-
+ efl_webview/lib/webview.cc                         | 192 ++++++++++++++-------
+ efl_webview/lib/webview.h                          |  29 +++-
+ efl_webview/public/xwalk_main.cc                   |   2 +-
+ efl_webview/public/xwalk_view.cc                   |  39 ++---
+ efl_webview/public/xwalk_view.h                    |   2 +-
+ 8 files changed, 170 insertions(+), 102 deletions(-)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 1e12159..76b19f3 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -200,11 +200,11 @@ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
+ void RenderWidgetHostViewEfl::InitAsChild(
+     gfx::NativeView parent_view) {
+-  preserve_window_ = gfx::PreserveWindow::Create(this, evas_object_evas_get(parent_view));
++  preserve_window_.reset(gfx::PreserveWindow::Create(this, evas_object_evas_get(parent_view)));
+   evas_object_size_hint_align_set(preserve_window_->SmartObject(), EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_box_pack_end(parent_view, preserve_window_->SmartObject());
+   evas_object_show(preserve_window_->SmartObject());
++  evas_object_box_append(parent_view, preserve_window_->SmartObject());
+   compositing_surface_ = preserve_window_->EmbeddedXWindow();
+ }
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.h b/content/browser/renderer_host/render_widget_host_view_efl.h
+index e20f51b..f047e35 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.h
++++ b/content/browser/renderer_host/render_widget_host_view_efl.h
+@@ -287,7 +287,7 @@ class CONTENT_EXPORT RenderWidgetHostViewEfl
+   gfx::PluginWindowHandle compositing_surface_;
+-  gfx::PreserveWindow* preserve_window_;
++  scoped_ptr<gfx::PreserveWindow> preserve_window_;
+   scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
+ };
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index 6dac4e8..b9ece50 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -103,7 +103,7 @@ static void window_create()
+   evas_object_show(url_entry);
+   /* Create WebView */
+-  Evas_Object* web_view = xwalk_view_add(elm_window);
++  Evas_Object* web_view = xwalk_view_add(evas_object_evas_get(elm_window));
+   evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND,
+                                    EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(web_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index 61ecb96..ae886e7 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -4,10 +4,6 @@
+ #include "efl_webview/lib/webview.h"
+-#include <Elementary.h>
+-
+-#include <map>
+-
+ #include "base/command_line.h"
+ #include "base/file_util.h"
+ #include "base/files/file_path.h"
+@@ -20,35 +16,108 @@
+ namespace {
+-typedef std::map<const Evas_Object*, xwalk::WebView*> EvasWebViewMap;
++const char evas_smart_xwalk_view_type[] = "Evas_Smart_Xwalk_View";
++
++struct XWalk_View_Smart_Data {
++    Evas_Object_Box_Data base_;
++    xwalk::WebViewPrivate* priv_;
++};
++
++bool IsXWalkViewEvasObject(const Evas_Object* evas_object) {
++  DCHECK(evas_object);
++
++  const char* evas_object_type = evas_object_type_get(evas_object);
++  if (!evas_object_smart_type_check(evas_object, evas_smart_xwalk_view_type)) {
++    LOG(ERROR) << evas_object << " is not of an "
++               << evas_object_type << "!";
++    return false;
++  }
++
++  const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
++  if (!evas_smart) {
++    LOG(ERROR) << evas_object << "("
++               << evas_object_type << ") is not a smart object!";
++    return false;
++  }
++
++  const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
++  if (!smart_class) {
++    LOG(ERROR) << evas_object << "("
++               << evas_object_type << ") is not a smart class object!";
++    return false;
++  }
++
++  return true;
++}
++
++inline XWalk_View_Smart_Data* ToSmartData(const Evas_Object* evas_object) {
++  DCHECK(evas_object);
++  DCHECK(IsXWalkViewEvasObject(evas_object));
++  CHECK(evas_object_smart_data_get(evas_object));
++  return static_cast<XWalk_View_Smart_Data*>(
++            evas_object_smart_data_get(evas_object));
++}
++
++EVAS_SMART_SUBCLASS_NEW(evas_smart_xwalk_view_type, xwalk_view,
++                        Evas_Object_Box_Api, Evas_Object_Box_Api,
++                        evas_object_box_smart_class_get, 0);
++
++void xwalk_view_smart_add(Evas_Object* o) {
++  XWalk_View_Smart_Data* smart_data =
++        static_cast<XWalk_View_Smart_Data*>(evas_object_smart_data_get(o));
+-inline EvasWebViewMap& EvasObjectToWebViewMap() {
+-// FIXME: Temporary solution until web view has its own smart class.
+-  static EvasWebViewMap map;
+-  return map;
++  if (!smart_data) {
++    smart_data = static_cast<XWalk_View_Smart_Data*>(
++        calloc(1, sizeof(XWalk_View_Smart_Data)));
++
++    const Evas_Smart* smart = evas_object_smart_smart_get(o);
++    const Evas_Smart_Class* smart_class = evas_smart_class_get(smart);
++    smart_data->base_.api =
++        reinterpret_cast<const Evas_Object_Box_Api*>(smart_class);
++
++    smart_data->priv_ = 0;
++
++    evas_object_smart_data_set(o, smart_data);
++  }
++
++  xwalk_view_parent_sc->base.add(o);
++}
++
++void xwalk_view_smart_del(Evas_Object* object) {
++  XWalk_View_Smart_Data* smart_data = ToSmartData(object);
++  DCHECK(smart_data->priv_);
++  delete smart_data->priv_;
++  xwalk_view_parent_sc->base.del(object);
++}
++
++void xwalk_view_smart_set_user(Evas_Object_Box_Api* smart_class) {
++  smart_class->base.add = xwalk_view_smart_add;
++  smart_class->base.del = xwalk_view_smart_del;
+ }
+ }  // namespace
+ namespace xwalk {
+-struct WebView::Private {
+-  Evas_Object* root_window;
+-  Evas_Object* view_box;
+-  scoped_refptr<WebRuntimeContext> context;
+-  scoped_ptr<WebContentsDelegateXWalk> webContentsDelegate;
+-  static GURL s_startup_url;
+-};
++GURL WebViewPrivate::s_startup_url = GURL();
+-GURL WebView::Private::s_startup_url = GURL();
++Evas_Object* CreateWebView(Evas* canvas) {
++  DCHECK(canvas);
+-// static
+-WebView* WebView::Create(Evas_Object* root_window) {
+-  return new WebView(root_window);
++  Evas_Object* view_object =
++      evas_object_smart_add(canvas, xwalk_view_smart_class_new());
++
++  XWalk_View_Smart_Data* smart_data = ToSmartData(view_object);
++  DCHECK(smart_data);
++
++  DCHECK(!smart_data->priv_);
++  smart_data->priv_ = new WebViewPrivate(view_object);
++
++  return view_object;
+ }
+ // static
+-void WebView::CommandLineInit(int argc, char** argv) {
++void WebViewPrivate::CommandLineInit(int argc, char** argv) {
+   CommandLine::Init(argc, argv);
+   CommandLine* command_line = CommandLine::ForCurrentProcess();
+@@ -61,86 +130,75 @@ void WebView::CommandLineInit(int argc, char** argv) {
+   if (!(url.is_valid() && url.has_scheme()))
+     url = net::FilePathToFileURL(base::FilePath(args[0]));
+-  WebView::Private::s_startup_url = GURL(url);
++  WebViewPrivate::s_startup_url = GURL(url);
+ }
+-WebView::WebView(Evas_Object* root_window)
+-    : private_(new Private) {
++WebViewPrivate::WebViewPrivate(Evas_Object* view_object)
++    : view_object_(view_object)
++    , context_(WebRuntimeContext::current()) {
+   {
+-    if (!WebView::Private::s_startup_url.is_valid())
+-      WebView::Private::s_startup_url = GURL("about:blank");
++    if (!WebViewPrivate::s_startup_url.is_valid())
++      WebViewPrivate::s_startup_url = GURL("about:blank");
+   }
+-  private_->root_window = root_window;
+-  private_->view_box = elm_box_add(private_->root_window);
+-  // FIXME: In future this has to be a separate Smart Class representing web view.
+-  // 'this' should be set as smart_data->priv
+-  EvasObjectToWebViewMap()[private_->view_box] = this;
+-
+-  elm_object_focus_allow_set(private_->view_box, EINA_TRUE);
+-
+-  private_->context = WebRuntimeContext::current();
++  DCHECK(view_object_);
+   content::BrowserContext* browser_context =
+-      private_->context->BrowserContext();
+-  private_->webContentsDelegate.reset(
+-      new WebContentsDelegateXWalk(browser_context, private_->view_box));
++      context_->BrowserContext();
++  web_contents_delegate_.reset(
++      new WebContentsDelegateXWalk(browser_context, view_object_));
+   content::WebContentsViewEfl* content_view =
+-      static_cast<content::WebContentsViewEfl*>(private_->
+-          webContentsDelegate->WebContents()->GetView());
+-  // FIXME: Don't pass elm_box to WebContentsViewEfl. Need focus handling of PreserveWindow evas object here.
+-  content_view->SetViewContainerBox(private_->view_box);
++      static_cast<content::WebContentsViewEfl*>(web_contents_delegate_->
++          WebContents()->GetView());
++  content_view->SetViewContainerBox(view_object_);
+   static_cast<WebContentsViewDelegateXWalk*>(content_view->delegate())->
+-      SetViewContainerBox(private_->view_box);
++      SetViewContainerBox(view_object_);
+-  LoadURL(WebView::Private::s_startup_url);
++  LoadURL(WebViewPrivate::s_startup_url);
+ }
+-WebView::~WebView() {
+-// FIXME : And by the way who will invoke it?
+-  EvasObjectToWebViewMap().erase(private_->view_box);
+-  evas_object_del(private_->view_box);
++WebViewPrivate::~WebViewPrivate() {
+ }
+-bool WebView::CanGoBack() const {
+-  return private_->webContentsDelegate->WebContents()->GetController().CanGoBack();
++bool WebViewPrivate::CanGoBack() const {
++  return web_contents_delegate_->WebContents()->GetController().CanGoBack();
+ }
+-bool WebView::CanGoForward() const {
+-  return private_->webContentsDelegate->WebContents()->GetController().CanGoForward();
++bool WebViewPrivate::CanGoForward() const {
++  return web_contents_delegate_->WebContents()->GetController().CanGoForward();
+ }
+-void WebView::GoForward() {
+-  private_->webContentsDelegate->WebContents()->GetController().GoForward();
++void WebViewPrivate::GoForward() {
++  web_contents_delegate_->WebContents()->GetController().GoForward();
+ }
+-void WebView::GoBack() {
+-  private_->webContentsDelegate->WebContents()->GetController().GoBack();
++void WebViewPrivate::GoBack() {
++  web_contents_delegate_->WebContents()->GetController().GoBack();
+ }
+-void WebView::Reload() {
+-  private_->webContentsDelegate->WebContents()->GetController().Reload(false);
++void WebViewPrivate::Reload() {
++  web_contents_delegate_->WebContents()->GetController().Reload(false);
+ }
+-void WebView::LoadURL(const GURL& url) {
++void WebViewPrivate::LoadURL(const GURL& url) {
+   url_ = EinaSharedString(url.spec());
+   content::NavigationController::LoadURLParams params(url);
+   params.transition_type = content::PageTransitionFromInt(
+       content::PAGE_TRANSITION_TYPED |
+       content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
+-  private_->webContentsDelegate->WebContents()->
++  web_contents_delegate_->WebContents()->
+       GetController().LoadURLWithParams(params);
+-  private_->webContentsDelegate->WebContents()->GetView()->Focus();
++  web_contents_delegate_->WebContents()->GetView()->Focus();
+ }
+-Evas_Object* WebView::EvasObject() {
+-  return private_->view_box;
++Evas_Object* WebViewPrivate::EvasObject() {
++  return view_object_;
+ }
+-WebView* ToWebView(const Evas_Object* evas_object) {
+-  EvasWebViewMap::iterator found = EvasObjectToWebViewMap().find(evas_object);
+-  if (found != EvasObjectToWebViewMap().end())
+-    return found->second;
++WebViewPrivate* ToWebViewPrivate(const Evas_Object* evas_object) {
++  if (evas_object && IsXWalkViewEvasObject(evas_object))
++    return ToSmartData(evas_object)->priv_;
++
+   return 0;
+ }
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index ae4f98f..62a5772 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -8,18 +8,21 @@
+ #include <Evas.h>
+ #include "base/basictypes.h"
++#include "base/memory/ref_counted.h"
+ #include "base/memory/scoped_ptr.h"
+ #include "base/strings/efl/eina_shared_string.h"
+ #include "googleurl/src/gurl.h"
+ namespace xwalk {
+-class EAPI WebView {
++class WebContentsDelegateXWalk;
++class WebRuntimeContext;
++
++class WebViewPrivate {
+  public:
+-  EAPI static WebView* Create(Evas_Object* root_window);
+-  EAPI static void CommandLineInit(int argc, char** argv);
++  static void CommandLineInit(int argc, char** argv);
+-  ~WebView();
++  ~WebViewPrivate();
+   EAPI Evas_Object* EvasObject();
+@@ -33,16 +36,24 @@ class EAPI WebView {
+   const char* url() const { return url_; }
+  private:
+-  explicit WebView(Evas_Object* root_window);
++  explicit WebViewPrivate(Evas_Object* evas_object);
+-  struct Private;
+-  scoped_ptr<Private> private_;
++  Evas_Object* view_object_;
++  scoped_refptr<WebRuntimeContext> context_;
++  scoped_ptr<WebContentsDelegateXWalk> web_contents_delegate_;
+   EinaSharedString url_;
+-  DISALLOW_COPY_AND_ASSIGN(WebView);
++  static GURL s_startup_url;
++
++  friend Evas_Object* CreateWebView(Evas* canvas);
++
++  DISALLOW_COPY_AND_ASSIGN(WebViewPrivate);
+ };
+-WebView* ToWebView(const Evas_Object*);
++
++Evas_Object* CreateWebView(Evas* canvas);
++
++WebViewPrivate* ToWebViewPrivate(const Evas_Object* web_view);
+ }  // namespace xwalk
+diff --git a/efl_webview/public/xwalk_main.cc b/efl_webview/public/xwalk_main.cc
+index 218c55d..2dfc902 100644
+--- a/efl_webview/public/xwalk_main.cc
++++ b/efl_webview/public/xwalk_main.cc
+@@ -6,5 +6,5 @@
+ #include "efl_webview/lib/webview.h"
+ void xwalk_init(int argc, char *argv[]) {
+-  xwalk::WebView::CommandLineInit(argc, argv);
++  xwalk::WebViewPrivate::CommandLineInit(argc, argv);
+ }
+diff --git a/efl_webview/public/xwalk_view.cc b/efl_webview/public/xwalk_view.cc
+index b000143..0acd334 100644
+--- a/efl_webview/public/xwalk_view.cc
++++ b/efl_webview/public/xwalk_view.cc
+@@ -5,55 +5,54 @@
+ #include "efl_webview/public/xwalk_view.h"
+ #include "efl_webview/lib/webview.h"
+-using namespace xwalk;
+-
+-#define XWALK_VIEW_GET_IMPL_OR_RETURN(xwalk_view, impl, ...)         \
+-  WebView* impl = ToWebView(xwalk_view);                             \
++#define XWALK_VIEW_GET_PRIVATE_OR_RETURN(xwalk_view, priv, ...)      \
++  xwalk::WebViewPrivate* priv = xwalk::ToWebViewPrivate(xwalk_view); \
+   do {                                                               \
+-    if (!impl) {                                                     \
++    if (!priv) {                                                     \
+       EINA_LOG_CRIT("no private data for object %p", xwalk_view);    \
+       return __VA_ARGS__;                                            \
+     }                                                                \
+   } while (0)
+-Evas_Object* xwalk_view_add(Evas_Object* root_window) {
+-  return WebView::Create(root_window)->EvasObject();
++Evas_Object* xwalk_view_add(Evas* canvas) {
++  EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
++
++  return xwalk::CreateWebView(canvas);
+ }
+ Eina_Bool xwalk_view_url_set(Evas_Object* evas_object, const char* url) {
+-  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
++  XWALK_VIEW_GET_PRIVATE_OR_RETURN(evas_object, priv, false);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(url, false);
+-  impl->LoadURL(GURL(url));
++  priv->LoadURL(GURL(url));
+   return true;
+ }
+ const char* xwalk_view_url_get(const Evas_Object* evas_object) {
+-  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, "");
+-  return impl->url();
++  XWALK_VIEW_GET_PRIVATE_OR_RETURN(evas_object, priv, "");
++  return priv->url();
+ }
+ Eina_Bool xwalk_view_reload(Evas_Object* evas_object) {
+-  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
+-  impl->Reload();
+-
++  XWALK_VIEW_GET_PRIVATE_OR_RETURN(evas_object, priv, false);
++  priv->Reload();
+   return true;
+ }
+ Eina_Bool xwalk_view_back(Evas_Object* evas_object) {
+-  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
+-  if (impl->CanGoBack()) {
+-    impl->GoBack();
++  XWALK_VIEW_GET_PRIVATE_OR_RETURN(evas_object, priv, false);
++  if (priv->CanGoBack()) {
++    priv->GoBack();
+     return true;
+   }
+   return false;
+ }
+ Eina_Bool xwalk_view_forward(Evas_Object* evas_object) {
+-  XWALK_VIEW_GET_IMPL_OR_RETURN(evas_object, impl, false);
+-  if (impl->CanGoForward()) {
+-    impl->GoForward();
++  XWALK_VIEW_GET_PRIVATE_OR_RETURN(evas_object, priv, false);
++  if (priv->CanGoForward()) {
++    priv->GoForward();
+     return true;
+   }
+   return false;
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+index a4c85d58..fbde786 100644
+--- a/efl_webview/public/xwalk_view.h
++++ b/efl_webview/public/xwalk_view.h
+@@ -11,7 +11,7 @@
+ extern "C" {
+ #endif
+-EAPI Evas_Object *xwalk_view_add(Evas_Object *root_window);
++EAPI Evas_Object *xwalk_view_add(Evas *canvas);
+ EAPI Eina_Bool xwalk_view_url_set(Evas_Object *obj, const char *url);
+-- 
+1.8.1.2
+
diff --git a/patchset/0013-Remove-view-from-the-container-when-rwhv-is-deleted.patch b/patchset/0013-Remove-view-from-the-container-when-rwhv-is-deleted.patch
new file mode 100644 (file)
index 0000000..4bfe4e5
--- /dev/null
@@ -0,0 +1,77 @@
+From a18be822f69e47b681cbc4760f7263bc64b46790 Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Thu, 1 Aug 2013 16:09:21 +0300
+Subject: [PATCH 13/33] Remove view from the container when rwhv is deleted
+
+---
+ content/browser/web_contents/web_contents_view_efl.cc | 18 ++++++++++++++++++
+ content/browser/web_contents/web_contents_view_efl.h  |  3 +++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index 3885d0b..6e22d05 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -42,6 +42,17 @@ WebContentsViewEfl::WebContentsViewEfl(
+     : web_contents_(web_contents),
+       delegate_(delegate),
+       view_container_box_(0) {
++  /*
++   * TODO: Connect the evas smart callback signals for size changes to
++   * callback functions in this file.
++   */
++
++  /* TODO: do we need a focus store for our EFL widget */
++
++  // TODO: Initializiation function for delegate that takes an evas_object
++  // if (delegate_)
++  //    delegate_->Initialize(expanded_.get(), &focus_store_);
++  Observe(web_contents);
+ }
+ WebContentsViewEfl::~WebContentsViewEfl() {
+@@ -140,6 +151,13 @@ void WebContentsViewEfl::SizeContents(const gfx::Size& size) {
+ void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
+ }
++void WebContentsViewEfl::RenderViewDeleted(RenderViewHost* render_view_host) {
++  if (view_container_box_ && render_view_host->GetView()) {
++    gfx::NativeView native_view = render_view_host->GetView()->GetNativeView();
++    evas_object_box_remove(view_container_box_, native_view);
++  }
++}
++
+ void WebContentsViewEfl::RenderViewSwappedIn(RenderViewHost* host) {
+   UpdateDragDest(host);
+ }
+diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
+index e481009..91aab48 100644
+--- a/content/browser/web_contents/web_contents_view_efl.h
++++ b/content/browser/web_contents/web_contents_view_efl.h
+@@ -12,6 +12,7 @@
+ #include "content/common/drag_event_source_info.h"
+ #include "content/port/browser/render_view_host_delegate_view.h"
+ #include "content/port/browser/web_contents_view_port.h"
++#include "content/public/browser/web_contents_observer.h"
+ #include <Evas.h>
+@@ -23,6 +24,7 @@ class WebContentsViewDelegate;
+ class CONTENT_EXPORT WebContentsViewEfl
+     : public WebContentsViewPort,
++      public WebContentsObserver,
+       public RenderViewHostDelegateView {
+  public:
+   WebContentsViewEfl(WebContentsImpl* web_contents,
+@@ -57,6 +59,7 @@ class CONTENT_EXPORT WebContentsViewEfl
+       RenderWidgetHost* render_widget_host) OVERRIDE;
+   virtual void SetPageTitle(const string16& title) OVERRIDE;
+   virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
++  virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE;
+   virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
+   virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
+-- 
+1.8.1.2
+
diff --git a/patchset/0014-Use-WebContentsViewDelegate-GetNativeView-instead-of.patch b/patchset/0014-Use-WebContentsViewDelegate-GetNativeView-instead-of.patch
new file mode 100644 (file)
index 0000000..e77f943
--- /dev/null
@@ -0,0 +1,367 @@
+From 43ebc6ad31d9467c443ee9e5ed9ccf8423cca1b5 Mon Sep 17 00:00:00 2001
+From: Dongseong Hwang <dongseong.hwang@intel.com>
+Date: Wed, 31 Jul 2013 15:51:45 +0300
+Subject: [PATCH 14/33] Use WebContentsViewDelegate::GetNativeView() instead of
+ making redundant WebContentsViewEfl::SetViewContainerBox().
+
+An embeder already can pass a container view to WebContentsView via
+WebContentsViewDelegate, but we added redundant SetViewContainerBox() to pass a
+containter view.
+This patch removes WebContentsViewEfl::SetViewContainerBox() and uses
+WebContentsViewDelegate::GetNativeView().
+---
+ .../renderer_host/render_widget_host_view_efl.cc   |  9 ++++++---
+ .../browser/web_contents/web_contents_view_efl.cc  | 21 ++++++++++++++-------
+ .../browser/web_contents/web_contents_view_efl.h   |  7 -------
+ .../public/browser/web_contents_view_delegate.h    |  1 +
+ content/shell/shell.cc                             |  2 ++
+ content/shell/shell.h                              |  1 +
+ content/shell/shell_efl.cc                         | 22 ++++++++++++----------
+ content/shell/shell_web_contents_view_delegate.h   |  5 +++++
+ .../shell/shell_web_contents_view_delegate_efl.cc  | 18 ++++++++++++------
+ .../lib/web_contents_view_delegate_xwalk.cc        | 14 +++++++++-----
+ efl_webview/lib/web_contents_view_delegate_xwalk.h |  5 +++--
+ efl_webview/lib/webview.cc                         |  3 +--
+ 12 files changed, 66 insertions(+), 42 deletions(-)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 76b19f3..67dc2dd 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -200,9 +200,12 @@ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
+ void RenderWidgetHostViewEfl::InitAsChild(
+     gfx::NativeView parent_view) {
+-  preserve_window_.reset(gfx::PreserveWindow::Create(this, evas_object_evas_get(parent_view)));
+-  evas_object_size_hint_align_set(preserve_window_->SmartObject(), EVAS_HINT_FILL, EVAS_HINT_FILL);
+-  evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  preserve_window_.reset(gfx::PreserveWindow::Create(
++      this, evas_object_evas_get(parent_view)));
++  evas_object_size_hint_align_set(preserve_window_->SmartObject(),
++                                  EVAS_HINT_FILL, EVAS_HINT_FILL);
++  evas_object_size_hint_weight_set(preserve_window_->SmartObject(),
++                                   EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(preserve_window_->SmartObject());
+   evas_object_box_append(parent_view, preserve_window_->SmartObject());
+   compositing_surface_ = preserve_window_->EmbeddedXWindow();
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index 6e22d05..7c8a43a 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -40,8 +40,7 @@ WebContentsViewEfl::WebContentsViewEfl(
+     WebContentsImpl* web_contents,
+     WebContentsViewDelegate* delegate)
+     : web_contents_(web_contents),
+-      delegate_(delegate),
+-      view_container_box_(0) {
++      delegate_(delegate) {
+   /*
+    * TODO: Connect the evas smart callback signals for size changes to
+    * callback functions in this file.
+@@ -59,7 +58,9 @@ WebContentsViewEfl::~WebContentsViewEfl() {
+ }
+ gfx::NativeView WebContentsViewEfl::GetNativeView() const {
+-  return GetContentNativeView();
++  if (delegate_)
++    return delegate_->GetNativeView();
++  return NULL;
+ }
+ gfx::NativeView WebContentsViewEfl::GetContentNativeView() const {
+@@ -123,7 +124,14 @@ RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
+   RenderWidgetHostView* view =
+       RenderWidgetHostView::CreateViewForWidget(render_widget_host);
+-  view->InitAsChild(view_container_box_);
++  view->InitAsChild(GetNativeView());
++  // gfx::NativeView content_view = view->GetNativeView();
++
++  // TODO: Connect EFL focus event to self
++  // InsertIntoContentArea(content_view);
++
++  // We don't want to change any state in this class for swapped out RVHs
++  // because they will not be visible at this time.
+   if (render_widget_host->IsRenderView()) {
+     RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
+     if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
+@@ -152,9 +160,8 @@ void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
+ }
+ void WebContentsViewEfl::RenderViewDeleted(RenderViewHost* render_view_host) {
+-  if (view_container_box_ && render_view_host->GetView()) {
+-    gfx::NativeView native_view = render_view_host->GetView()->GetNativeView();
+-    evas_object_box_remove(view_container_box_, native_view);
++  if (GetNativeView() && GetContentNativeView()) {
++    evas_object_box_remove(GetNativeView(), GetContentNativeView());
+   }
+ }
+diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
+index 91aab48..6266de6 100644
+--- a/content/browser/web_contents/web_contents_view_efl.h
++++ b/content/browser/web_contents/web_contents_view_efl.h
+@@ -14,8 +14,6 @@
+ #include "content/port/browser/web_contents_view_port.h"
+ #include "content/public/browser/web_contents_observer.h"
+-#include <Evas.h>
+-
+ namespace content {
+ class WebContents;
+@@ -83,9 +81,6 @@ class CONTENT_EXPORT WebContentsViewEfl
+   virtual void GotFocus() OVERRIDE;
+   virtual void TakeFocus(bool reverse) OVERRIDE;
+-  void SetViewContainerBox(Evas_Object* container_box) { view_container_box_ = container_box; }
+-  Evas_Object* ViewContainerBox() { return view_container_box_; }
+-
+  private:
+   void UpdateDragDest(RenderViewHost* new_host);
+@@ -93,8 +88,6 @@ class CONTENT_EXPORT WebContentsViewEfl
+   scoped_ptr<WebContentsViewDelegate> delegate_;
+-  Evas_Object* view_container_box_;
+-
+   // The size we want the view to be.  We keep this in a separate variable
+   // because resizing in GTK+ is async.
+   gfx::Size requested_size_;
+diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h
+index aec9701..5d92ff4 100644
+--- a/content/public/browser/web_contents_view_delegate.h
++++ b/content/public/browser/web_contents_view_delegate.h
+@@ -82,6 +82,7 @@ class CONTENT_EXPORT WebContentsViewDelegate {
+       CreateRenderWidgetHostViewDelegate(
+           RenderWidgetHost* render_widget_host) = 0;
+ #elif defined(TOOLKIT_EFL)
++  virtual gfx::NativeView GetNativeView() const = 0;
+   virtual void Focus() = 0;
+ #endif
+ };
+diff --git a/content/shell/shell.cc b/content/shell/shell.cc
+index 9e6576e..94c7e28 100644
+--- a/content/shell/shell.cc
++++ b/content/shell/shell.cc
+@@ -49,6 +49,8 @@ Shell::Shell(WebContents* web_contents)
+       url_edit_view_(NULL),
+ #if defined(OS_WIN) && !defined(USE_AURA)
+       default_edit_wnd_proc_(0),
++#elif defined(TOOLKIT_EFL)
++      container_view_(NULL),
+ #endif
+       headless_(false) {
+   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+diff --git a/content/shell/shell.h b/content/shell/shell.h
+index 2d9ba10..a108c7d 100644
+--- a/content/shell/shell.h
++++ b/content/shell/shell.h
+@@ -237,6 +237,7 @@ class Shell : public WebContentsDelegate,
+ #elif defined(TOOLKIT_EFL)
+   int content_width_;
+   int content_height_;
++  gfx::NativeView container_view_;
+ #elif defined(TOOLKIT_GTK)
+   GtkWidget* vbox_;
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+index e4ec4e5..f847113 100644
+--- a/content/shell/shell_efl.cc
++++ b/content/shell/shell_efl.cc
+@@ -12,14 +12,15 @@
+ #include "base/logging.h"
+ #include "base/strings/string_piece.h"
+ #include "base/utf_string_conversions.h"
++#include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/browser/browser_context.h"
+ #include "content/public/browser/native_web_keyboard_event.h"
+ #include "content/public/browser/web_contents.h"
+ #include "content/public/browser/web_contents_view.h"
+-#include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/common/renderer_preferences.h"
+ #include "content/shell/shell_browser_context.h"
+ #include "content/shell/shell_content_browser_client.h"
++#include "content/shell/shell_web_contents_view_delegate.h"
+ namespace content {
+@@ -64,13 +65,17 @@ void Shell::PlatformSetContents() {
+   if (headless_)
+     return;
+-  Evas_Object* view_box = elm_box_add(window_);
+-  evas_object_size_hint_weight_set(view_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  container_view_ = elm_box_add(window_);
++  evas_object_size_hint_weight_set(container_view_,
++                                   EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  elm_win_resize_object_add(window_, view_box);
++  elm_win_resize_object_add(window_, container_view_);
++  evas_object_show(container_view_);
+-  WebContentsView* content_view = web_contents_->GetView();
+-  static_cast<WebContentsViewEfl*>(content_view)->SetViewContainerBox(view_box);
++  content::WebContentsViewEfl* content_view =
++      static_cast<content::WebContentsViewEfl*>(web_contents_->GetView());
++  static_cast<ShellWebContentsViewDelegate*>(content_view->delegate())->
++      SetNativeView(container_view_);
+ }
+ void Shell::SizeTo(int width, int height) {
+@@ -107,10 +112,7 @@ void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
+ bool Shell::TakeFocus(WebContents* source, bool reverse) {
+   DCHECK(source == web_contents_.get());
+-  WebContentsView* content_view = web_contents_->GetView();
+-  Evas_Object* view_box =
+-      static_cast<WebContentsViewEfl*>(content_view)->ViewContainerBox();
+-  elm_object_focus_next(view_box,
++  elm_object_focus_next(container_view_,
+                         reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
+   return true;
+ }
+diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
+index 8352438..cb93fbf 100644
+--- a/content/shell/shell_web_contents_view_delegate.h
++++ b/content/shell/shell_web_contents_view_delegate.h
+@@ -48,6 +48,9 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+   virtual void TakeFocus(bool reverse) OVERRIDE;
+   virtual void SizeChanged(const gfx::Size& size) OVERRIDE;
+   void MenuItemSelected(int selection);
++#elif defined(TOOLKIT_EFL)
++  virtual gfx::NativeView GetNativeView() const OVERRIDE;
++  void SetNativeView(gfx::NativeView);
+ #endif
+  private:
+@@ -76,6 +79,8 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+                        OnDeleteMenuActivated);
+   CHROMEGTK_CALLBACK_0(ShellWebContentsViewDelegate, void,
+                        OnInspectMenuActivated);
++#elif defined(TOOLKIT_EFL)
++  gfx::NativeView native_view_;
+ #endif
+   DISALLOW_COPY_AND_ASSIGN(ShellWebContentsViewDelegate);
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+index 60aaa16..0720a5c 100644
+--- a/content/shell/shell_web_contents_view_delegate_efl.cc
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -6,7 +6,6 @@
+ #include <Elementary.h>
+ #include "base/command_line.h"
+-#include "content/browser/web_contents/web_contents_view_efl.h"
+ #include "content/public/browser/render_process_host.h"
+ #include "content/public/browser/render_view_host.h"
+ #include "content/public/browser/render_widget_host_view.h"
+@@ -33,7 +32,8 @@ WebContentsViewDelegate* CreateShellWebContentsViewDelegate(
+ ShellWebContentsViewDelegate::ShellWebContentsViewDelegate(
+     WebContents* web_contents)
+-    : web_contents_(web_contents) {
++    : web_contents_(web_contents),
++      native_view_(NULL) {
+ }
+ ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() {
+@@ -51,10 +51,16 @@ WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
+ }
+ void ShellWebContentsViewDelegate::Focus() {
+-  WebContentsView* content_view = web_contents_->GetView();
+-  Evas_Object* view_box =
+-      static_cast<WebContentsViewEfl*>(content_view)->ViewContainerBox();
+-  elm_object_focus_set(view_box, EINA_TRUE);
++  if (native_view_)
++    elm_object_focus_set(native_view_, EINA_TRUE);
++}
++
++gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const {
++  return native_view_;
++}
++
++void ShellWebContentsViewDelegate::SetNativeView(gfx::NativeView native_view) {
++  native_view_ = native_view;
+ }
+ }  // namespace content
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.cc b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+index 40b59f7..7160227 100644
+--- a/efl_webview/lib/web_contents_view_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+@@ -11,16 +11,20 @@ namespace xwalk {
+ WebContentsViewDelegateXWalk::WebContentsViewDelegateXWalk(
+     content::WebContents* web_contents)
+     : web_contents_(web_contents)
+-    , view_box_(NULL) {
++    , native_view_(NULL) {
+ }
+ WebContentsViewDelegateXWalk::~WebContentsViewDelegateXWalk() {
+ }
+ void WebContentsViewDelegateXWalk::Focus() {
+-  if (!view_box_)
++  if (!native_view_)
+     return;
+-  elm_object_focus_set(view_box_, EINA_TRUE);
++  elm_object_focus_set(native_view_, EINA_TRUE);
++}
++
++gfx::NativeView WebContentsViewDelegateXWalk::GetNativeView() const {
++  return native_view_;
+ }
+ void WebContentsViewDelegateXWalk::ShowContextMenu(
+@@ -33,8 +37,8 @@ content::WebDragDestDelegate*
+   return NULL;
+ }
+-void WebContentsViewDelegateXWalk::SetViewContainerBox(Evas_Object* view_box) {
+-  view_box_ = view_box;
++void WebContentsViewDelegateXWalk::SetNativeView(Evas_Object* native_view) {
++  native_view_ = native_view;
+ }
+ }  // namespace xwalk
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.h b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+index d5df813..ef0fa59 100644
+--- a/efl_webview/lib/web_contents_view_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+@@ -25,12 +25,13 @@ class WebContentsViewDelegateXWalk : public content::WebContentsViewDelegate {
+       content::ContextMenuSourceType type) OVERRIDE;
+   virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE;
+   virtual void Focus() OVERRIDE;
++  virtual gfx::NativeView GetNativeView() const OVERRIDE;
+-  void SetViewContainerBox(Evas_Object*);
++  void SetNativeView(Evas_Object*);
+  private:
+   content::WebContents* web_contents_;
+-  Evas_Object* view_box_;
++  Evas_Object* native_view_;
+   DISALLOW_COPY_AND_ASSIGN(WebContentsViewDelegateXWalk);
+ };
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index ae886e7..bb48b59 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -150,9 +150,8 @@ WebViewPrivate::WebViewPrivate(Evas_Object* view_object)
+   content::WebContentsViewEfl* content_view =
+       static_cast<content::WebContentsViewEfl*>(web_contents_delegate_->
+           WebContents()->GetView());
+-  content_view->SetViewContainerBox(view_object_);
+   static_cast<WebContentsViewDelegateXWalk*>(content_view->delegate())->
+-      SetViewContainerBox(view_object_);
++      SetNativeView(view_object_);
+   LoadURL(WebViewPrivate::s_startup_url);
+ }
+-- 
+1.8.1.2
+
diff --git a/patchset/0015-Load-progress-api.patch b/patchset/0015-Load-progress-api.patch
new file mode 100644 (file)
index 0000000..6792957
--- /dev/null
@@ -0,0 +1,357 @@
+From 7b21f6d20c6cde7f7309413a2176bc2fe0c70809 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Fri, 2 Aug 2013 16:27:42 +0300
+Subject: [PATCH 15/33] Load progress api.
+
+---
+ content/browser/web_contents/web_contents_impl.cc |  2 +-
+ content/public/browser/web_contents_delegate.h    |  2 +-
+ efl_webview/examples/main.cc                      | 13 +++-
+ efl_webview/lib/web_contents_delegate_xwalk.cc    | 18 ++++--
+ efl_webview/lib/web_contents_delegate_xwalk.h     | 17 +++--
+ efl_webview/lib/webview.cc                        | 26 ++++----
+ efl_webview/lib/webview.h                         |  8 ++-
+ efl_webview/lib/webview_callbacks.h               | 77 +++++++++++++++++++++++
+ efl_webview/public/xwalk_view.h                   | 12 +++-
+ 9 files changed, 144 insertions(+), 31 deletions(-)
+ create mode 100644 efl_webview/lib/webview_callbacks.h
+
+diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
+index 43ec8e5..9e70e1e 100644
+--- a/content/browser/web_contents/web_contents_impl.cc
++++ b/content/browser/web_contents/web_contents_impl.cc
+@@ -2938,7 +2938,7 @@ void WebContentsImpl::DidCancelLoading() {
+ }
+ void WebContentsImpl::DidChangeLoadProgress(double progress) {
+-#if defined(OS_ANDROID)
++#if defined(OS_ANDROID) || defined(TOOLKIT_EFL)
+   if (delegate_)
+     delegate_->LoadProgressChanged(this, progress);
+ #endif
+diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
+index 60732ce..866de0d 100644
+--- a/content/public/browser/web_contents_delegate.h
++++ b/content/public/browser/web_contents_delegate.h
+@@ -109,7 +109,7 @@ class CONTENT_EXPORT WebContentsDelegate {
+   // loading feedback. See WebContents::IsLoading()
+   virtual void LoadingStateChanged(WebContents* source) {}
+-#if defined(OS_ANDROID)
++#if defined(OS_ANDROID) || defined(TOOLKIT_EFL)
+   // Notifies the delegate that the page has made some progress loading.
+   // |progress| is a value between 0.0 (nothing loaded) to 1.0 (page fully
+   // loaded).
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index b9ece50..f1c06d2 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -41,10 +41,16 @@ static void
+ on_url_entry_activated(void *user_data, Evas_Object *url_entry,
+                        void *event_info)
+ {
+-    const char* url = elm_entry_entry_get(url_entry);
+-    xwalk_view_url_set((Evas_Object*)user_data, url);
++  const char* url = elm_entry_entry_get(url_entry);
++  xwalk_view_url_set((Evas_Object*)user_data, url);
+ }
++static void
++on_progress(void *user_data, Evas_Object *xwalk_view, void *event_info)
++{
++  /* double progress = *(double *)event_info; */
++  /* FIXME : implement. */
++}
+ static void window_create()
+ {
+@@ -120,6 +126,9 @@ static void window_create()
+   evas_object_smart_callback_add(url_entry, "activated",
+                                  on_url_entry_activated, web_view);
++  evas_object_smart_callback_add(web_view, "load,progress",
++                                 on_progress, elm_window);
++
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+ }
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.cc b/efl_webview/lib/web_contents_delegate_xwalk.cc
+index a6cb3a3..6272029 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_delegate_xwalk.cc
+@@ -7,18 +7,19 @@
+ #include <Elementary.h>
+ #include "content/public/browser/web_contents.h"
+ #include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
++#include "efl_webview/lib/webview.h"
+ namespace xwalk {
+ namespace {
+ const int g_window_width = 800;
+ const int g_window_height = 600;
+-} // namespace
++
++}  // namespace
+ WebContentsDelegateXWalk::WebContentsDelegateXWalk(
+-    content::BrowserContext* browser_context, Evas_Object* view_box)
+-    : view_box_(view_box)
+-{
++    content::BrowserContext* browser_context, WebViewPrivate* web_view)
++    : web_view_(web_view) {
+   content::WebContents::CreateParams create_params(browser_context, 0);
+   create_params.initial_size = gfx::Size(g_window_width, g_window_height);
+@@ -26,10 +27,15 @@ WebContentsDelegateXWalk::WebContentsDelegateXWalk(
+   web_contents_->SetDelegate(this);
+ }
++void WebContentsDelegateXWalk::LoadProgressChanged(content::WebContents* source,
++                                 double progress) {
++  web_view_->SmartCallback<webviewcallbacks::LoadProgress>().Call(&progress);
++}
++
+ bool WebContentsDelegateXWalk::TakeFocus(
+     content::WebContents* source, bool reverse) {
+-  elm_object_focus_next(view_box_,
+-                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
++//  elm_object_focus_next(web_view_,
++//                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
+   return true;
+ }
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.h b/efl_webview/lib/web_contents_delegate_xwalk.h
+index 182d2e8..1b3d972 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_delegate_xwalk.h
+@@ -16,20 +16,25 @@ class WebContentsViewDelegate;
+ namespace xwalk {
+-class WebContentsDelegateXWalk : public content::WebContentsDelegate
+-{
++class WebViewPrivate;
++
++class WebContentsDelegateXWalk : public content::WebContentsDelegate {
+  public:
+-  WebContentsDelegateXWalk(content::BrowserContext*, Evas_Object*);
++  WebContentsDelegateXWalk(content::BrowserContext*, WebViewPrivate*);
++
++  virtual void LoadProgressChanged(content::WebContents* source,
++                                   double progress) OVERRIDE;
++
+   virtual bool TakeFocus(content::WebContents* source,
+                          bool reverse) OVERRIDE;
+   content::WebContents* WebContents() { return web_contents_.get(); }
+  private:
+-  Evas_Object* view_box_;
++  WebViewPrivate* web_view_;
+   scoped_ptr<content::WebContents> web_contents_;
+ };
+-} // namespace xwalk
++}  // namespace xwalk
+-#endif // EFL_WEBVIEW_LIB_WEB_CONTENTS_DELEGATE_XWALK_H_
++#endif  // EFL_WEBVIEW_LIB_WEB_CONTENTS_DELEGATE_XWALK_H_
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index bb48b59..c9d559f 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -16,11 +16,17 @@
+ namespace {
++namespace callbacks = xwalk::webviewcallbacks;
++
+ const char evas_smart_xwalk_view_type[] = "Evas_Smart_Xwalk_View";
++const Evas_Smart_Cb_Description g_smart_callbacks[] = {
++  {callbacks::CallbackName<callbacks::LoadProgress>(), "d"},
++  {NULL, NULL}};
++
+ struct XWalk_View_Smart_Data {
+-    Evas_Object_Box_Data base_;
+-    xwalk::WebViewPrivate* priv_;
++  Evas_Object_Box_Data base_;
++  xwalk::WebViewPrivate* priv_;
+ };
+ bool IsXWalkViewEvasObject(const Evas_Object* evas_object) {
+@@ -60,7 +66,7 @@ inline XWalk_View_Smart_Data* ToSmartData(const Evas_Object* evas_object) {
+ EVAS_SMART_SUBCLASS_NEW(evas_smart_xwalk_view_type, xwalk_view,
+                         Evas_Object_Box_Api, Evas_Object_Box_Api,
+-                        evas_object_box_smart_class_get, 0);
++                        evas_object_box_smart_class_get, g_smart_callbacks);
+ void xwalk_view_smart_add(Evas_Object* o) {
+   XWalk_View_Smart_Data* smart_data =
+@@ -135,17 +141,13 @@ void WebViewPrivate::CommandLineInit(int argc, char** argv) {
+ WebViewPrivate::WebViewPrivate(Evas_Object* view_object)
+     : view_object_(view_object)
+-    , context_(WebRuntimeContext::current()) {
+-  {
+-    if (!WebViewPrivate::s_startup_url.is_valid())
+-      WebViewPrivate::s_startup_url = GURL("about:blank");
+-  }
++    , context_(WebRuntimeContext::current())
++    , web_contents_delegate_(
++          new WebContentsDelegateXWalk(context_->BrowserContext(), this)) {
++  if (!WebViewPrivate::s_startup_url.is_valid())
++    WebViewPrivate::s_startup_url = GURL("about:blank");
+   DCHECK(view_object_);
+-  content::BrowserContext* browser_context =
+-      context_->BrowserContext();
+-  web_contents_delegate_.reset(
+-      new WebContentsDelegateXWalk(browser_context, view_object_));
+   content::WebContentsViewEfl* content_view =
+       static_cast<content::WebContentsViewEfl*>(web_contents_delegate_->
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index 62a5772..b5d9a7b 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -11,6 +11,7 @@
+ #include "base/memory/ref_counted.h"
+ #include "base/memory/scoped_ptr.h"
+ #include "base/strings/efl/eina_shared_string.h"
++#include "efl_webview/lib/webview_callbacks.h"
+ #include "googleurl/src/gurl.h"
+ namespace xwalk {
+@@ -18,7 +19,7 @@ namespace xwalk {
+ class WebContentsDelegateXWalk;
+ class WebRuntimeContext;
+-class WebViewPrivate {
++class WebViewPrivate {  // FIXME : Consider renaming.
+  public:
+   static void CommandLineInit(int argc, char** argv);
+@@ -35,6 +36,11 @@ class WebViewPrivate {
+   const char* url() const { return url_; }
++  template<webviewcallbacks::CallbackType type>
++  webviewcallbacks::Callback<type> SmartCallback() const {
++      return webviewcallbacks::Callback<type>(view_object_);
++  }
++
+  private:
+   explicit WebViewPrivate(Evas_Object* evas_object);
+diff --git a/efl_webview/lib/webview_callbacks.h b/efl_webview/lib/webview_callbacks.h
+new file mode 100644
+index 0000000..af67471
+--- /dev/null
++++ b/efl_webview/lib/webview_callbacks.h
+@@ -0,0 +1,77 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#ifndef EFL_WEBVIEW_LIB_WEBVIEW_CALLBACKS_H_
++#define EFL_WEBVIEW_LIB_WEBVIEW_CALLBACKS_H_
++
++#include <Evas.h>
++
++namespace xwalk {
++
++namespace webviewcallbacks {
++
++enum CallbackType {
++    LoadProgress
++};
++
++template <CallbackType>
++struct CallBackInfo;
++
++template <CallbackType type>
++const char* CallbackName() { return CallBackInfo<type>::name(); }
++
++class EvasObjectHolder {
++ protected:
++  explicit EvasObjectHolder(Evas_Object* object)
++    : m_object(object) {
++  }
++
++  Evas_Object* m_object;
++};
++
++template <CallbackType callbackType,
++          typename ArgType = typename CallBackInfo<callbackType>::Type>
++struct Callback: public EvasObjectHolder {
++  explicit Callback(Evas_Object* view) : EvasObjectHolder(view) { }
++
++  void Call(ArgType argument) {
++    evas_object_smart_callback_call(m_object, CallbackName<callbackType>(),
++                                    static_cast<void*>(argument));
++  }
++};
++
++template <CallbackType callbackType>
++struct Callback <callbackType, void> : public EvasObjectHolder {
++  explicit Callback(Evas_Object* view) : EvasObjectHolder(view) { }
++
++  void Call() {
++    evas_object_smart_callback_call(m_object, CallbackName<callbackType>(), 0);
++  }
++};
++
++template <CallbackType callbackType>
++struct Callback <callbackType, const char*> : public EvasObjectHolder {
++  explicit Callback(Evas_Object* view) : EvasObjectHolder(view) { }
++
++  void Call(const char* arg) {
++    evas_object_smart_callback_call(m_object, CallbackName<callbackType>(),
++                                    const_cast<char*>(arg));
++  }
++};
++
++#define DECLARE_XWALK_VIEW_CALLBACK(callbackType, literal, type) \
++template <>                                                      \
++struct CallBackInfo<callbackType> {                              \
++    typedef type Type;                                           \
++    static const char* name() { return literal; }                \
++}
++
++// Note: type 'void' means that no arguments are expected.
++DECLARE_XWALK_VIEW_CALLBACK(LoadProgress, "load,progress", double*);
++
++}  // namespace webviewcallbacks
++
++}  // namespace xwalk
++
++#endif  // EFL_WEBVIEW_LIB_WEBVIEW_CALLBACKS_H_
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+index fbde786..4758e41 100644
+--- a/efl_webview/public/xwalk_view.h
++++ b/efl_webview/public/xwalk_view.h
+@@ -2,8 +2,16 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+-#ifndef EFL_WEBVIEW_PUBLIC_XWALK_VIEW_H_
+-#define EFL_WEBVIEW_PUBLIC_XWALK_VIEW_H_
++/**
++ * @file xwalk_view.h
++ *
++ * The following signals (see evas_object_smart_callback_add()) are emitted:
++ *
++ * - "load,progress", double*: load progress has changed (value from 0.0 to 1.0).
++ */
++
++#ifndef xwalk_view_h
++#define xwalk_view_h
+ #include <Evas.h>
+-- 
+1.8.1.2
+
diff --git a/patchset/0016-Update-page-title-API.patch b/patchset/0016-Update-page-title-API.patch
new file mode 100644 (file)
index 0000000..ebcdd79
--- /dev/null
@@ -0,0 +1,247 @@
+From e991e5d9d5fb16a278a33109888bd182d83f554e Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Mon, 5 Aug 2013 14:47:28 +0300
+Subject: [PATCH 16/33] Update page title API.
+
+---
+ base/strings/efl/eina_shared_string.cc               |  4 ++++
+ base/strings/efl/eina_shared_string.h                | 20 +++++++++++---------
+ .../browser/web_contents/web_contents_view_efl.cc    |  1 +
+ content/public/browser/web_contents_view_delegate.h  |  3 +++
+ content/shell/shell_web_contents_view_delegate.h     |  1 +
+ .../shell/shell_web_contents_view_delegate_efl.cc    |  3 +++
+ efl_webview/examples/main.cc                         |  9 +++++++++
+ efl_webview/lib/web_contents_view_delegate_xwalk.cc  |  6 ++++++
+ efl_webview/lib/web_contents_view_delegate_xwalk.h   |  1 +
+ efl_webview/lib/webview.cc                           |  1 +
+ efl_webview/lib/webview_callbacks.h                  |  4 +++-
+ 11 files changed, 43 insertions(+), 10 deletions(-)
+
+diff --git a/base/strings/efl/eina_shared_string.cc b/base/strings/efl/eina_shared_string.cc
+index 48b4862..48bf291 100644
+--- a/base/strings/efl/eina_shared_string.cc
++++ b/base/strings/efl/eina_shared_string.cc
+@@ -16,6 +16,10 @@ EinaSharedString::EinaSharedString(const std::string& str)
+   : string_(eina_stringshare_add(str.c_str())) {
+ }
++EinaSharedString::EinaSharedString(const string16& str)
++  : string_(eina_stringshare_add(std::string(str.begin(), str.end()).c_str())) {
++}
++
+ EinaSharedString::~EinaSharedString() {
+   if (string_)
+     eina_stringshare_del(string_);
+diff --git a/base/strings/efl/eina_shared_string.h b/base/strings/efl/eina_shared_string.h
+index 6fc0aee..b9752f1 100644
+--- a/base/strings/efl/eina_shared_string.h
++++ b/base/strings/efl/eina_shared_string.h
+@@ -2,23 +2,25 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+-#ifndef EINA_SHARED_STRING_H_
+-#define EINA_SHARED_STRING_H_
+-
+-#include "base/base_export.h"
++#ifndef BASE_STRINGS_EFL_EINA_SHARED_STRING_H_
++#define BASE_STRINGS_EFL_EINA_SHARED_STRING_H_
+ #include <Eina.h>
+ #include <string>
++#include "base/base_export.h"
++#include "base/string16.h"
++
+ namespace base {
+ class BASE_EXPORT EinaSharedString {
+-public:
++ public:
+   EinaSharedString() : string_(0) { }
+   EinaSharedString(const EinaSharedString& other);
+   EinaSharedString(const char* str);
+   explicit EinaSharedString(const std::string&);
++  explicit EinaSharedString(const string16&);
+   ~EinaSharedString();
+@@ -39,14 +41,14 @@ public:
+   size_t Length() const { return string_ ? static_cast<size_t>(eina_stringshare_strlen(string_)) : 0; }
+-  static EinaSharedString Adopt(Eina_Stringshare*);
++  static EinaSharedString Adopt(Eina_Stringshare* str);
+-private:
++ private:
+   const char* string_;
+ };
+-} // namespace base
++}  // namespace base
+ using base::EinaSharedString;
+-#endif // EINA_SHARED_STRING_H_
++#endif  // BASE_STRINGS_EFL_EINA_SHARED_STRING_H_
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index 7c8a43a..371231c 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -147,6 +147,7 @@ RenderWidgetHostView* WebContentsViewEfl::CreateViewForPopupWidget(
+ }
+ void WebContentsViewEfl::SetPageTitle(const string16& title) {
++  delegate_->UpdateTitle(title);
+ }
+ void WebContentsViewEfl::SizeContents(const gfx::Size& size) {
+diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h
+index 5d92ff4..7f13957 100644
+--- a/content/public/browser/web_contents_view_delegate.h
++++ b/content/public/browser/web_contents_view_delegate.h
+@@ -9,6 +9,8 @@
+ #include <gtk/gtk.h>
+ #elif defined(OS_MACOSX)
+ #import <Cocoa/Cocoa.h>
++#elif defined(TOOLKIT_EFL)
++#include "base/string16.h"
+ #endif
+ #include "content/common/content_export.h"
+@@ -84,6 +86,7 @@ class CONTENT_EXPORT WebContentsViewDelegate {
+ #elif defined(TOOLKIT_EFL)
+   virtual gfx::NativeView GetNativeView() const = 0;
+   virtual void Focus() = 0;
++  virtual void UpdateTitle(const string16& title) = 0;
+ #endif
+ };
+diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
+index cb93fbf..2bdb6dd 100644
+--- a/content/shell/shell_web_contents_view_delegate.h
++++ b/content/shell/shell_web_contents_view_delegate.h
+@@ -49,6 +49,7 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
+   virtual void SizeChanged(const gfx::Size& size) OVERRIDE;
+   void MenuItemSelected(int selection);
+ #elif defined(TOOLKIT_EFL)
++  virtual void UpdateTitle(const string16& title) OVERRIDE;
+   virtual gfx::NativeView GetNativeView() const OVERRIDE;
+   void SetNativeView(gfx::NativeView);
+ #endif
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+index 0720a5c..8221da0 100644
+--- a/content/shell/shell_web_contents_view_delegate_efl.cc
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -55,6 +55,9 @@ void ShellWebContentsViewDelegate::Focus() {
+     elm_object_focus_set(native_view_, EINA_TRUE);
+ }
++void ShellWebContentsViewDelegate::UpdateTitle(const string16& title) {
++}
++
+ gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const {
+   return native_view_;
+ }
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index f1c06d2..0197d1a 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -52,6 +52,13 @@ on_progress(void *user_data, Evas_Object *xwalk_view, void *event_info)
+   /* FIXME : implement. */
+ }
++static void
++on_title_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
++{
++    const char *title = (const char *)event_info;
++    elm_win_title_set((Evas_Object*)user_data, title);
++}
++
+ static void window_create()
+ {
+   /* Create elementary window */
+@@ -128,6 +135,8 @@ static void window_create()
+   evas_object_smart_callback_add(web_view, "load,progress",
+                                  on_progress, elm_window);
++  evas_object_smart_callback_add(web_view, "title,changed",
++                                 on_title_changed, elm_window);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.cc b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+index 7160227..0b4c686 100644
+--- a/efl_webview/lib/web_contents_view_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+@@ -3,6 +3,7 @@
+ // found in the LICENSE file.
+ #include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
++#include "efl_webview/lib/webview.h"
+ #include <Elementary.h>
+@@ -23,6 +24,11 @@ void WebContentsViewDelegateXWalk::Focus() {
+   elm_object_focus_set(native_view_, EINA_TRUE);
+ }
++void WebContentsViewDelegateXWalk::UpdateTitle(const string16& title) {
++  ToWebViewPrivate(native_view_)->SmartCallback<webviewcallbacks::TitleChange>()
++                                  .Call(EinaSharedString(title));
++}
++
+ gfx::NativeView WebContentsViewDelegateXWalk::GetNativeView() const {
+   return native_view_;
+ }
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.h b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+index ef0fa59..7de4723 100644
+--- a/efl_webview/lib/web_contents_view_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.h
+@@ -25,6 +25,7 @@ class WebContentsViewDelegateXWalk : public content::WebContentsViewDelegate {
+       content::ContextMenuSourceType type) OVERRIDE;
+   virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE;
+   virtual void Focus() OVERRIDE;
++  virtual void UpdateTitle(const string16& title) OVERRIDE;
+   virtual gfx::NativeView GetNativeView() const OVERRIDE;
+   void SetNativeView(Evas_Object*);
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index c9d559f..e9d51f9 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -22,6 +22,7 @@ const char evas_smart_xwalk_view_type[] = "Evas_Smart_Xwalk_View";
+ const Evas_Smart_Cb_Description g_smart_callbacks[] = {
+   {callbacks::CallbackName<callbacks::LoadProgress>(), "d"},
++  {callbacks::CallbackName<callbacks::TitleChange>(), "s"},
+   {NULL, NULL}};
+ struct XWalk_View_Smart_Data {
+diff --git a/efl_webview/lib/webview_callbacks.h b/efl_webview/lib/webview_callbacks.h
+index af67471..a5f6092 100644
+--- a/efl_webview/lib/webview_callbacks.h
++++ b/efl_webview/lib/webview_callbacks.h
+@@ -12,7 +12,8 @@ namespace xwalk {
+ namespace webviewcallbacks {
+ enum CallbackType {
+-    LoadProgress
++  LoadProgress,
++  TitleChange
+ };
+ template <CallbackType>
+@@ -69,6 +70,7 @@ struct CallBackInfo<callbackType> {                              \
+ // Note: type 'void' means that no arguments are expected.
+ DECLARE_XWALK_VIEW_CALLBACK(LoadProgress, "load,progress", double*);
++DECLARE_XWALK_VIEW_CALLBACK(TitleChange, "title,changed", const char*);
+ }  // namespace webviewcallbacks
+-- 
+1.8.1.2
+
diff --git a/patchset/0017-URL-changed-API.patch b/patchset/0017-URL-changed-API.patch
new file mode 100644 (file)
index 0000000..44bd9d9
--- /dev/null
@@ -0,0 +1,211 @@
+From 8f389554f85471131da62f34f6f69b1d4d1ece16 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Mon, 5 Aug 2013 17:40:09 +0300
+Subject: [PATCH 17/33] URL changed API.
+
+---
+ efl_webview/examples/main.cc                   | 10 +++++++++
+ efl_webview/lib/web_contents_delegate_xwalk.cc |  5 +++++
+ efl_webview/lib/web_contents_delegate_xwalk.h  |  4 ++++
+ efl_webview/lib/webview.cc                     | 31 ++++++++++++++++++--------
+ efl_webview/lib/webview.h                      | 10 +++++++++
+ efl_webview/lib/webview_callbacks.h            |  5 +++--
+ efl_webview/public/xwalk_view.h                |  2 ++
+ 7 files changed, 56 insertions(+), 11 deletions(-)
+
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index 0197d1a..7ea8738 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -59,6 +59,14 @@ on_title_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
+     elm_win_title_set((Evas_Object*)user_data, title);
+ }
++static void
++on_url_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
++{
++    char *url = elm_entry_utf8_to_markup((const char *)event_info);
++    elm_entry_entry_set((Evas_Object*)user_data, url);
++    free(url);
++}
++
+ static void window_create()
+ {
+   /* Create elementary window */
+@@ -137,6 +145,8 @@ static void window_create()
+                                  on_progress, elm_window);
+   evas_object_smart_callback_add(web_view, "title,changed",
+                                  on_title_changed, elm_window);
++  evas_object_smart_callback_add(web_view, "url,changed",
++                                 on_url_changed, url_entry);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.cc b/efl_webview/lib/web_contents_delegate_xwalk.cc
+index 6272029..65024e6 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_delegate_xwalk.cc
+@@ -39,4 +39,9 @@ bool WebContentsDelegateXWalk::TakeFocus(
+   return true;
+ }
++void WebContentsDelegateXWalk::UpdateTargetURL(content::WebContents* source,
++                             int32 page_id, const GURL& url) {
++  web_view_->informURLChanged();
++}
++
+ }  // namespace xwalk
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.h b/efl_webview/lib/web_contents_delegate_xwalk.h
+index 1b3d972..7e143cb 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_delegate_xwalk.h
+@@ -28,6 +28,10 @@ class WebContentsDelegateXWalk : public content::WebContentsDelegate {
+   virtual bool TakeFocus(content::WebContents* source,
+                          bool reverse) OVERRIDE;
++  virtual void UpdateTargetURL(content::WebContents* source,
++                               int32 page_id,
++                               const GURL& url) OVERRIDE;
++
+   content::WebContents* WebContents() { return web_contents_.get(); }
+  private:
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index e9d51f9..3e4d467 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -8,6 +8,7 @@
+ #include "base/file_util.h"
+ #include "base/files/file_path.h"
+ #include "content/browser/web_contents/web_contents_view_efl.h"
++#include "content/public/browser/navigation_entry.h"
+ #include "content/public/browser/web_contents.h"
+ #include "efl_webview/lib/web_contents_delegate_xwalk.h"
+ #include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
+@@ -163,34 +164,46 @@ WebViewPrivate::~WebViewPrivate() {
+ }
+ bool WebViewPrivate::CanGoBack() const {
+-  return web_contents_delegate_->WebContents()->GetController().CanGoBack();
++  return NavigationController().CanGoBack();
+ }
+ bool WebViewPrivate::CanGoForward() const {
+-  return web_contents_delegate_->WebContents()->GetController().CanGoForward();
++  return NavigationController().CanGoForward();
+ }
+ void WebViewPrivate::GoForward() {
+-  web_contents_delegate_->WebContents()->GetController().GoForward();
++  NavigationController().GoForward();
+ }
+ void WebViewPrivate::GoBack() {
+-  web_contents_delegate_->WebContents()->GetController().GoBack();
++  NavigationController().GoBack();
+ }
+ void WebViewPrivate::Reload() {
+-  web_contents_delegate_->WebContents()->GetController().Reload(false);
++  NavigationController().Reload(false);
+ }
+ void WebViewPrivate::LoadURL(const GURL& url) {
+-  url_ = EinaSharedString(url.spec());
+   content::NavigationController::LoadURLParams params(url);
+   params.transition_type = content::PageTransitionFromInt(
+       content::PAGE_TRANSITION_TYPED |
+       content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
+-  web_contents_delegate_->WebContents()->
+-      GetController().LoadURLWithParams(params);
+-  web_contents_delegate_->WebContents()->GetView()->Focus();
++  NavigationController().LoadURLWithParams(params);
++}
++
++void WebViewPrivate::informURLChanged() {
++  const std::string& url_str = NavigationController().
++          GetActiveEntry()->GetURL().spec();
++  if (!url_str.compare(url_ ? url_ : ""))
++    return;
++
++  url_ = EinaSharedString(url_str);
++
++  SmartCallback<webviewcallbacks::URLChanged>().Call(url_);
++}
++
++inline content::NavigationController& WebViewPrivate::NavigationController() const {
++  return web_contents_delegate_->WebContents()->GetController();
+ }
+ Evas_Object* WebViewPrivate::EvasObject() {
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index b5d9a7b..43b6183 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -14,6 +14,12 @@
+ #include "efl_webview/lib/webview_callbacks.h"
+ #include "googleurl/src/gurl.h"
++namespace content {
++
++class NavigationController;
++
++}
++
+ namespace xwalk {
+ class WebContentsDelegateXWalk;
+@@ -41,9 +47,13 @@ class WebViewPrivate {  // FIXME : Consider renaming.
+       return webviewcallbacks::Callback<type>(view_object_);
+   }
++  void informURLChanged();
++
+  private:
+   explicit WebViewPrivate(Evas_Object* evas_object);
++  content::NavigationController& NavigationController() const;
++
+   Evas_Object* view_object_;
+   scoped_refptr<WebRuntimeContext> context_;
+   scoped_ptr<WebContentsDelegateXWalk> web_contents_delegate_;
+diff --git a/efl_webview/lib/webview_callbacks.h b/efl_webview/lib/webview_callbacks.h
+index a5f6092..241b1d6 100644
+--- a/efl_webview/lib/webview_callbacks.h
++++ b/efl_webview/lib/webview_callbacks.h
+@@ -13,7 +13,8 @@ namespace webviewcallbacks {
+ enum CallbackType {
+   LoadProgress,
+-  TitleChange
++  TitleChange,
++  URLChanged
+ };
+ template <CallbackType>
+@@ -71,7 +72,7 @@ struct CallBackInfo<callbackType> {                              \
+ // Note: type 'void' means that no arguments are expected.
+ DECLARE_XWALK_VIEW_CALLBACK(LoadProgress, "load,progress", double*);
+ DECLARE_XWALK_VIEW_CALLBACK(TitleChange, "title,changed", const char*);
+-
++DECLARE_XWALK_VIEW_CALLBACK(URLChanged, "url,changed", const char*);
+ }  // namespace webviewcallbacks
+ }  // namespace xwalk
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+index 4758e41..1e9077d 100644
+--- a/efl_webview/public/xwalk_view.h
++++ b/efl_webview/public/xwalk_view.h
+@@ -7,7 +7,9 @@
+  *
+  * The following signals (see evas_object_smart_callback_add()) are emitted:
+  *
++ * - "title,changed", const char*: title of the main frame was changed.
+  * - "load,progress", double*: load progress has changed (value from 0.0 to 1.0).
++ * - "url,changed", const char*: url of the main frame was changed.
+  */
+ #ifndef xwalk_view_h
+-- 
+1.8.1.2
+
diff --git a/patchset/0018-Add-documentation-to-xwalk-view-public-API.patch b/patchset/0018-Add-documentation-to-xwalk-view-public-API.patch
new file mode 100644 (file)
index 0000000..1e6e530
--- /dev/null
@@ -0,0 +1,81 @@
+From e38a6704ca9553ce21dec90254bac85d8b648bf3 Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Tue, 6 Aug 2013 10:53:08 +0300
+Subject: [PATCH 18/33] Add documentation to xwalk view public API
+
+---
+ efl_webview/public/xwalk_view.h | 49 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 48 insertions(+), 1 deletion(-)
+
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+index 1e9077d..680a5ab 100644
+--- a/efl_webview/public/xwalk_view.h
++++ b/efl_webview/public/xwalk_view.h
+@@ -21,16 +21,63 @@
+ extern "C" {
+ #endif
+-EAPI Evas_Object *xwalk_view_add(Evas *canvas);
++/**
++ * Creates a new EFL xwalk view object.
++ *
++ * @param evas canvas object where xwalk view should be created
++ *
++ * @return view object on success or @c NULL on failure
++ */
++EAPI Evas_Object *xwalk_view_add(Evas *evas);
++/**
++ * Asks xwalk view to load given URL.
++ *
++ * @param obj xwalk view object to load @a URL
++ * @param url uniform resource identifier to be loaded
++ *
++ * @return @c EINA_TRUE is returned if @a obj is valid, irrespective of load,
++ *         or @c EINA_FALSE on failure
++ */
+ EAPI Eina_Bool xwalk_view_url_set(Evas_Object *obj, const char *url);
++/**
++ * Returns current URL string of xwalk view object.
++ *
++ * It returns an internal string that should not
++ * be modified. The string is guaranteed to be stringshared.
++ *
++ * @param obj xwalk view object to get current URL
++ *
++ * @return current URL on success or @c NULL on failure
++ */
+ EAPI const char *xwalk_view_url_get(const Evas_Object *obj);
++/**
++ * Asks xwalk view to reload current document.
++ *
++ * @param obj xwalk view object to reload current document
++ *
++ * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise
++ */
+ EAPI Eina_Bool xwalk_view_reload(Evas_Object *obj);
++/**
++ * Asks xwalk view to navigate back in the history.
++ *
++ * @param obj xwalk view object to navigate back
++ *
++ * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise
++ */
+ EAPI Eina_Bool xwalk_view_back(Evas_Object *obj);
++/**
++ * Asks xwalk view to navigate forward in the history.
++ *
++ * @param obj xwalk view object to navigate forward
++ *
++ * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise
++ */
+ EAPI Eina_Bool xwalk_view_forward(Evas_Object *obj);
+ #ifdef __cplusplus
+-- 
+1.8.1.2
+
diff --git a/patchset/0019-Renaming.-Fixed-layout-while-loading-from-address-ba.patch b/patchset/0019-Renaming.-Fixed-layout-while-loading-from-address-ba.patch
new file mode 100644 (file)
index 0000000..0a0c9a3
--- /dev/null
@@ -0,0 +1,430 @@
+From 2717a30b8dfe9ad67c6fcceeb85d840ba4f1e081 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Thu, 8 Aug 2013 13:00:55 +0300
+Subject: [PATCH 19/33] Renaming. Fixed layout while loading from address bar.
+
+---
+ .../renderer_host/render_widget_host_view_efl.cc   |   5 +
+ .../browser/web_contents/web_contents_view_efl.cc  |   3 -
+ efl_webview/lib/web_contents_delegate_xwalk.cc     |   3 +-
+ efl_webview/lib/web_contents_delegate_xwalk.h      |   6 +-
+ .../lib/web_contents_view_delegate_xwalk.cc        |   6 +-
+ efl_webview/lib/webview.cc                         | 131 +++++++++++----------
+ efl_webview/lib/webview.h                          |  16 +--
+ efl_webview/public/xwalk_main.cc                   |   2 +-
+ efl_webview/public/xwalk_view.cc                   |   4 +-
+ 9 files changed, 90 insertions(+), 86 deletions(-)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 67dc2dd..e9f3ec9 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -200,6 +200,7 @@ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
+ void RenderWidgetHostViewEfl::InitAsChild(
+     gfx::NativeView parent_view) {
++  DCHECK(parent_view);
+   preserve_window_.reset(gfx::PreserveWindow::Create(
+       this, evas_object_evas_get(parent_view)));
+   evas_object_size_hint_align_set(preserve_window_->SmartObject(),
+@@ -207,6 +208,10 @@ void RenderWidgetHostViewEfl::InitAsChild(
+   evas_object_size_hint_weight_set(preserve_window_->SmartObject(),
+                                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(preserve_window_->SmartObject());
++
++  if (evas_object_box_children_get(parent_view))
++    evas_object_box_remove_all(parent_view, false);
++
+   evas_object_box_append(parent_view, preserve_window_->SmartObject());
+   compositing_surface_ = preserve_window_->EmbeddedXWindow();
+ }
+diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
+index 371231c..d44a7a9 100644
+--- a/content/browser/web_contents/web_contents_view_efl.cc
++++ b/content/browser/web_contents/web_contents_view_efl.cc
+@@ -161,9 +161,6 @@ void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
+ }
+ void WebContentsViewEfl::RenderViewDeleted(RenderViewHost* render_view_host) {
+-  if (GetNativeView() && GetContentNativeView()) {
+-    evas_object_box_remove(GetNativeView(), GetContentNativeView());
+-  }
+ }
+ void WebContentsViewEfl::RenderViewSwappedIn(RenderViewHost* host) {
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.cc b/efl_webview/lib/web_contents_delegate_xwalk.cc
+index 65024e6..8700b32 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_delegate_xwalk.cc
+@@ -4,7 +4,6 @@
+ #include "efl_webview/lib/web_contents_delegate_xwalk.h"
+-#include <Elementary.h>
+ #include "content/public/browser/web_contents.h"
+ #include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
+ #include "efl_webview/lib/webview.h"
+@@ -18,7 +17,7 @@ const int g_window_height = 600;
+ }  // namespace
+ WebContentsDelegateXWalk::WebContentsDelegateXWalk(
+-    content::BrowserContext* browser_context, WebViewPrivate* web_view)
++    content::BrowserContext* browser_context, WebView* web_view)
+     : web_view_(web_view) {
+   content::WebContents::CreateParams create_params(browser_context, 0);
+   create_params.initial_size = gfx::Size(g_window_width, g_window_height);
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.h b/efl_webview/lib/web_contents_delegate_xwalk.h
+index 7e143cb..fae5e68 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_delegate_xwalk.h
+@@ -16,11 +16,11 @@ class WebContentsViewDelegate;
+ namespace xwalk {
+-class WebViewPrivate;
++class WebView;
+ class WebContentsDelegateXWalk : public content::WebContentsDelegate {
+  public:
+-  WebContentsDelegateXWalk(content::BrowserContext*, WebViewPrivate*);
++  WebContentsDelegateXWalk(content::BrowserContext*, WebView*);
+   virtual void LoadProgressChanged(content::WebContents* source,
+                                    double progress) OVERRIDE;
+@@ -35,7 +35,7 @@ class WebContentsDelegateXWalk : public content::WebContentsDelegate {
+   content::WebContents* WebContents() { return web_contents_.get(); }
+  private:
+-  WebViewPrivate* web_view_;
++  WebView* web_view_;
+   scoped_ptr<content::WebContents> web_contents_;
+ };
+diff --git a/efl_webview/lib/web_contents_view_delegate_xwalk.cc b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+index 0b4c686..c48534b 100644
+--- a/efl_webview/lib/web_contents_view_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_view_delegate_xwalk.cc
+@@ -5,8 +5,6 @@
+ #include "efl_webview/lib/web_contents_view_delegate_xwalk.h"
+ #include "efl_webview/lib/webview.h"
+-#include <Elementary.h>
+-
+ namespace xwalk {
+ WebContentsViewDelegateXWalk::WebContentsViewDelegateXWalk(
+@@ -21,11 +19,11 @@ WebContentsViewDelegateXWalk::~WebContentsViewDelegateXWalk() {
+ void WebContentsViewDelegateXWalk::Focus() {
+   if (!native_view_)
+     return;
+-  elm_object_focus_set(native_view_, EINA_TRUE);
++  evas_object_focus_set(native_view_, EINA_TRUE);
+ }
+ void WebContentsViewDelegateXWalk::UpdateTitle(const string16& title) {
+-  ToWebViewPrivate(native_view_)->SmartCallback<webviewcallbacks::TitleChange>()
++  ToWebView(native_view_)->SmartCallback<webviewcallbacks::TitleChange>()
+                                   .Call(EinaSharedString(title));
+ }
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index 3e4d467..a60ac13 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -28,39 +28,12 @@ const Evas_Smart_Cb_Description g_smart_callbacks[] = {
+ struct XWalk_View_Smart_Data {
+   Evas_Object_Box_Data base_;
+-  xwalk::WebViewPrivate* priv_;
++  xwalk::WebView* priv_;
+ };
+-bool IsXWalkViewEvasObject(const Evas_Object* evas_object) {
+-  DCHECK(evas_object);
+-
+-  const char* evas_object_type = evas_object_type_get(evas_object);
+-  if (!evas_object_smart_type_check(evas_object, evas_smart_xwalk_view_type)) {
+-    LOG(ERROR) << evas_object << " is not of an "
+-               << evas_object_type << "!";
+-    return false;
+-  }
+-
+-  const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
+-  if (!evas_smart) {
+-    LOG(ERROR) << evas_object << "("
+-               << evas_object_type << ") is not a smart object!";
+-    return false;
+-  }
+-
+-  const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
+-  if (!smart_class) {
+-    LOG(ERROR) << evas_object << "("
+-               << evas_object_type << ") is not a smart class object!";
+-    return false;
+-  }
+-
+-  return true;
+-}
+-
+ inline XWalk_View_Smart_Data* ToSmartData(const Evas_Object* evas_object) {
+   DCHECK(evas_object);
+-  DCHECK(IsXWalkViewEvasObject(evas_object));
++  DCHECK(xwalk::IsWebViewEvasObject(evas_object));
+   CHECK(evas_object_smart_data_get(evas_object));
+   return static_cast<XWalk_View_Smart_Data*>(
+             evas_object_smart_data_get(evas_object));
+@@ -107,25 +80,10 @@ void xwalk_view_smart_set_user(Evas_Object_Box_Api* smart_class) {
+ namespace xwalk {
+-GURL WebViewPrivate::s_startup_url = GURL();
+-
+-Evas_Object* CreateWebView(Evas* canvas) {
+-  DCHECK(canvas);
+-
+-  Evas_Object* view_object =
+-      evas_object_smart_add(canvas, xwalk_view_smart_class_new());
+-
+-  XWalk_View_Smart_Data* smart_data = ToSmartData(view_object);
+-  DCHECK(smart_data);
+-
+-  DCHECK(!smart_data->priv_);
+-  smart_data->priv_ = new WebViewPrivate(view_object);
+-
+-  return view_object;
+-}
++GURL WebView::s_startup_url = GURL();
+ // static
+-void WebViewPrivate::CommandLineInit(int argc, char** argv) {
++void WebView::CommandLineInit(int argc, char** argv) {
+   CommandLine::Init(argc, argv);
+   CommandLine* command_line = CommandLine::ForCurrentProcess();
+@@ -138,16 +96,16 @@ void WebViewPrivate::CommandLineInit(int argc, char** argv) {
+   if (!(url.is_valid() && url.has_scheme()))
+     url = net::FilePathToFileURL(base::FilePath(args[0]));
+-  WebViewPrivate::s_startup_url = GURL(url);
++  WebView::s_startup_url = GURL(url);
+ }
+-WebViewPrivate::WebViewPrivate(Evas_Object* view_object)
++WebView::WebView(Evas_Object* view_object)
+     : view_object_(view_object)
+     , context_(WebRuntimeContext::current())
+     , web_contents_delegate_(
+           new WebContentsDelegateXWalk(context_->BrowserContext(), this)) {
+-  if (!WebViewPrivate::s_startup_url.is_valid())
+-    WebViewPrivate::s_startup_url = GURL("about:blank");
++  if (!WebView::s_startup_url.is_valid())
++    WebView::s_startup_url = GURL("about:blank");
+   DCHECK(view_object_);
+@@ -157,33 +115,33 @@ WebViewPrivate::WebViewPrivate(Evas_Object* view_object)
+   static_cast<WebContentsViewDelegateXWalk*>(content_view->delegate())->
+       SetNativeView(view_object_);
+-  LoadURL(WebViewPrivate::s_startup_url);
++  LoadURL(WebView::s_startup_url);
+ }
+-WebViewPrivate::~WebViewPrivate() {
++WebView::~WebView() {
+ }
+-bool WebViewPrivate::CanGoBack() const {
++bool WebView::CanGoBack() const {
+   return NavigationController().CanGoBack();
+ }
+-bool WebViewPrivate::CanGoForward() const {
++bool WebView::CanGoForward() const {
+   return NavigationController().CanGoForward();
+ }
+-void WebViewPrivate::GoForward() {
++void WebView::GoForward() {
+   NavigationController().GoForward();
+ }
+-void WebViewPrivate::GoBack() {
++void WebView::GoBack() {
+   NavigationController().GoBack();
+ }
+-void WebViewPrivate::Reload() {
++void WebView::Reload() {
+   NavigationController().Reload(false);
+ }
+-void WebViewPrivate::LoadURL(const GURL& url) {
++void WebView::LoadURL(const GURL& url) {
+   content::NavigationController::LoadURLParams params(url);
+   params.transition_type = content::PageTransitionFromInt(
+       content::PAGE_TRANSITION_TYPED |
+@@ -191,7 +149,7 @@ void WebViewPrivate::LoadURL(const GURL& url) {
+   NavigationController().LoadURLWithParams(params);
+ }
+-void WebViewPrivate::informURLChanged() {
++void WebView::informURLChanged() {
+   const std::string& url_str = NavigationController().
+           GetActiveEntry()->GetURL().spec();
+   if (!url_str.compare(url_ ? url_ : ""))
+@@ -202,19 +160,66 @@ void WebViewPrivate::informURLChanged() {
+   SmartCallback<webviewcallbacks::URLChanged>().Call(url_);
+ }
+-inline content::NavigationController& WebViewPrivate::NavigationController() const {
++inline content::NavigationController& WebView::NavigationController() const {
+   return web_contents_delegate_->WebContents()->GetController();
+ }
+-Evas_Object* WebViewPrivate::EvasObject() {
++Evas_Object* WebView::EvasObject() {
+   return view_object_;
+ }
+-WebViewPrivate* ToWebViewPrivate(const Evas_Object* evas_object) {
+-  if (evas_object && IsXWalkViewEvasObject(evas_object))
++Evas_Object* CreateWebViewEvasObject(Evas* canvas) {
++  DCHECK(canvas);
++
++  Evas_Object* view_object =
++      evas_object_smart_add(canvas, xwalk_view_smart_class_new());
++
++  XWalk_View_Smart_Data* smart_data = ToSmartData(view_object);
++  DCHECK(smart_data);
++
++  DCHECK(!smart_data->priv_);
++  smart_data->priv_ = new WebView(view_object);
++
++  evas_object_size_hint_align_set(view_object,
++                                  EVAS_HINT_FILL, EVAS_HINT_FILL);
++  evas_object_size_hint_weight_set(view_object,
++                                   EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++
++  return view_object;
++}
++
++WebView* ToWebView(const Evas_Object* evas_object) {
++  if (evas_object && IsWebViewEvasObject(evas_object))
+     return ToSmartData(evas_object)->priv_;
+   return 0;
+ }
++bool IsWebViewEvasObject(const Evas_Object* evas_object) {
++  DCHECK(evas_object);
++
++  const char* evas_object_type = evas_object_type_get(evas_object);
++  if (!evas_object_smart_type_check(evas_object, evas_smart_xwalk_view_type)) {
++    LOG(ERROR) << evas_object << " is not of an "
++               << evas_object_type << "!";
++    return false;
++  }
++
++  const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
++  if (!evas_smart) {
++    LOG(ERROR) << evas_object << "("
++               << evas_object_type << ") is not a smart object!";
++    return false;
++  }
++
++  const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
++  if (!smart_class) {
++    LOG(ERROR) << evas_object << "("
++               << evas_object_type << ") is not a smart class object!";
++    return false;
++  }
++
++  return true;
++}
++
+ }  // namespace xwalk
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index 43b6183..985ef160 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -25,11 +25,11 @@ namespace xwalk {
+ class WebContentsDelegateXWalk;
+ class WebRuntimeContext;
+-class WebViewPrivate {  // FIXME : Consider renaming.
++class WebView {
+  public:
+   static void CommandLineInit(int argc, char** argv);
+-  ~WebViewPrivate();
++  ~WebView();
+   EAPI Evas_Object* EvasObject();
+@@ -50,7 +50,7 @@ class WebViewPrivate {  // FIXME : Consider renaming.
+   void informURLChanged();
+  private:
+-  explicit WebViewPrivate(Evas_Object* evas_object);
++  explicit WebView(Evas_Object* evas_object);
+   content::NavigationController& NavigationController() const;
+@@ -61,15 +61,15 @@ class WebViewPrivate {  // FIXME : Consider renaming.
+   static GURL s_startup_url;
+-  friend Evas_Object* CreateWebView(Evas* canvas);
++  friend Evas_Object* CreateWebViewEvasObject(Evas* canvas);
+-  DISALLOW_COPY_AND_ASSIGN(WebViewPrivate);
++  DISALLOW_COPY_AND_ASSIGN(WebView);
+ };
++Evas_Object* CreateWebViewEvasObject(Evas* canvas);
+-Evas_Object* CreateWebView(Evas* canvas);
+-
+-WebViewPrivate* ToWebViewPrivate(const Evas_Object* web_view);
++WebView* ToWebView(const Evas_Object* evas_object);
++bool IsWebViewEvasObject(const Evas_Object* evas_object);
+ }  // namespace xwalk
+diff --git a/efl_webview/public/xwalk_main.cc b/efl_webview/public/xwalk_main.cc
+index 2dfc902..218c55d 100644
+--- a/efl_webview/public/xwalk_main.cc
++++ b/efl_webview/public/xwalk_main.cc
+@@ -6,5 +6,5 @@
+ #include "efl_webview/lib/webview.h"
+ void xwalk_init(int argc, char *argv[]) {
+-  xwalk::WebViewPrivate::CommandLineInit(argc, argv);
++  xwalk::WebView::CommandLineInit(argc, argv);
+ }
+diff --git a/efl_webview/public/xwalk_view.cc b/efl_webview/public/xwalk_view.cc
+index 0acd334..5893224 100644
+--- a/efl_webview/public/xwalk_view.cc
++++ b/efl_webview/public/xwalk_view.cc
+@@ -6,7 +6,7 @@
+ #include "efl_webview/lib/webview.h"
+ #define XWALK_VIEW_GET_PRIVATE_OR_RETURN(xwalk_view, priv, ...)      \
+-  xwalk::WebViewPrivate* priv = xwalk::ToWebViewPrivate(xwalk_view); \
++  xwalk::WebView* priv = xwalk::ToWebView(xwalk_view);               \
+   do {                                                               \
+     if (!priv) {                                                     \
+       EINA_LOG_CRIT("no private data for object %p", xwalk_view);    \
+@@ -18,7 +18,7 @@
+ Evas_Object* xwalk_view_add(Evas* canvas) {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
+-  return xwalk::CreateWebView(canvas);
++  return xwalk::CreateWebViewEvasObject(canvas);
+ }
+ Eina_Bool xwalk_view_url_set(Evas_Object* evas_object, const char* url) {
+-- 
+1.8.1.2
+
diff --git a/patchset/0020-UTF8-window-titles.patch b/patchset/0020-UTF8-window-titles.patch
new file mode 100644 (file)
index 0000000..971ebca
--- /dev/null
@@ -0,0 +1,41 @@
+From e43b95f1c1f74ab70798e32b148b47127e760557 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Fri, 9 Aug 2013 12:42:23 +0300
+Subject: [PATCH 20/33] UTF8 window titles.
+
+---
+ base/strings/efl/eina_shared_string.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/base/strings/efl/eina_shared_string.cc b/base/strings/efl/eina_shared_string.cc
+index 48bf291..036e4a4 100644
+--- a/base/strings/efl/eina_shared_string.cc
++++ b/base/strings/efl/eina_shared_string.cc
+@@ -3,6 +3,9 @@
+ // found in the LICENSE file.
+ #include "base/strings/efl/eina_shared_string.h"
++#include "base/strings/utf_string_conversions.h"
++
++namespace base {
+ EinaSharedString::EinaSharedString(const EinaSharedString& other)
+   : string_(eina_stringshare_ref(other.string_)) {
+@@ -17,7 +20,7 @@ EinaSharedString::EinaSharedString(const std::string& str)
+ }
+ EinaSharedString::EinaSharedString(const string16& str)
+-  : string_(eina_stringshare_add(std::string(str.begin(), str.end()).c_str())) {
++  : string_(eina_stringshare_add(UTF16ToUTF8(str).c_str())) {
+ }
+ EinaSharedString::~EinaSharedString() {
+@@ -55,3 +58,5 @@ Eina_Stringshare* EinaSharedString::LeakString() {
+   return sharedString;
+ }
++
++}  // namespace base
+-- 
+1.8.1.2
+
diff --git a/patchset/0021-Add-loading-indication-API-and-use-it-in-example-app.patch b/patchset/0021-Add-loading-indication-API-and-use-it-in-example-app.patch
new file mode 100644 (file)
index 0000000..d949034
--- /dev/null
@@ -0,0 +1,143 @@
+From 42b9ec78f75f8b0b48487e340eaae31e0ab07305 Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Thu, 8 Aug 2013 17:48:37 +0300
+Subject: [PATCH 21/33] Add loading indication API and use it in example
+ application
+
+---
+ efl_webview/examples/main.cc                   | 19 +++++++++++++++++++
+ efl_webview/lib/web_contents_delegate_xwalk.cc |  8 +++++---
+ efl_webview/lib/web_contents_delegate_xwalk.h  |  3 +--
+ efl_webview/lib/webview.cc                     |  2 +-
+ efl_webview/lib/webview_callbacks.h            |  4 ++--
+ efl_webview/public/xwalk_view.h                |  2 +-
+ 6 files changed, 29 insertions(+), 9 deletions(-)
+
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+index 7ea8738..c0cbf4b 100644
+--- a/efl_webview/examples/main.cc
++++ b/efl_webview/examples/main.cc
+@@ -67,6 +67,14 @@ on_url_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
+     free(url);
+ }
++static void
++on_loadingstate_changed(void *user_data,
++                        Evas_Object *xwalk_view,
++                        void *event_info)
++{
++  elm_progressbar_pulse((Evas_Object*)user_data, *(bool*)event_info);
++}
++
+ static void window_create()
+ {
+   /* Create elementary window */
+@@ -123,6 +131,15 @@ static void window_create()
+   elm_box_pack_end(horizontal_layout, url_entry);
+   evas_object_show(url_entry);
++  Evas_Object* progress_bar = elm_progressbar_add(elm_window);
++  elm_progressbar_span_size_set(progress_bar, 10);
++  elm_progressbar_pulse_set(progress_bar, EINA_TRUE);
++  elm_progressbar_unit_format_set(progress_bar, NULL);
++  evas_object_size_hint_align_set(progress_bar, EVAS_HINT_FILL, 1);
++  evas_object_size_hint_weight_set(progress_bar, 0.01, EVAS_HINT_EXPAND);
++  elm_box_pack_end(horizontal_layout, progress_bar);
++  evas_object_show(progress_bar);
++
+   /* Create WebView */
+   Evas_Object* web_view = xwalk_view_add(evas_object_evas_get(elm_window));
+   evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND,
+@@ -147,6 +164,8 @@ static void window_create()
+                                  on_title_changed, elm_window);
+   evas_object_smart_callback_add(web_view, "url,changed",
+                                  on_url_changed, url_entry);
++  evas_object_smart_callback_add(web_view, "loadingstate,changed",
++                                 on_loadingstate_changed, progress_bar);
+   evas_object_resize(elm_window, window_width, window_height);
+   evas_object_show(elm_window);
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.cc b/efl_webview/lib/web_contents_delegate_xwalk.cc
+index 8700b32..d173fbc 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.cc
++++ b/efl_webview/lib/web_contents_delegate_xwalk.cc
+@@ -26,9 +26,11 @@ WebContentsDelegateXWalk::WebContentsDelegateXWalk(
+   web_contents_->SetDelegate(this);
+ }
+-void WebContentsDelegateXWalk::LoadProgressChanged(content::WebContents* source,
+-                                 double progress) {
+-  web_view_->SmartCallback<webviewcallbacks::LoadProgress>().Call(&progress);
++void WebContentsDelegateXWalk::LoadingStateChanged
++    (content::WebContents* source) {
++  bool is_loading = source->IsLoading();
++  web_view_->SmartCallback<webviewcallbacks::LoadingStateChanged>().Call(
++      &is_loading);
+ }
+ bool WebContentsDelegateXWalk::TakeFocus(
+diff --git a/efl_webview/lib/web_contents_delegate_xwalk.h b/efl_webview/lib/web_contents_delegate_xwalk.h
+index fae5e68..5fd1409 100644
+--- a/efl_webview/lib/web_contents_delegate_xwalk.h
++++ b/efl_webview/lib/web_contents_delegate_xwalk.h
+@@ -22,8 +22,7 @@ class WebContentsDelegateXWalk : public content::WebContentsDelegate {
+  public:
+   WebContentsDelegateXWalk(content::BrowserContext*, WebView*);
+-  virtual void LoadProgressChanged(content::WebContents* source,
+-                                   double progress) OVERRIDE;
++  virtual void LoadingStateChanged(content::WebContents* source) OVERRIDE;
+   virtual bool TakeFocus(content::WebContents* source,
+                          bool reverse) OVERRIDE;
+diff --git a/efl_webview/lib/webview.cc b/efl_webview/lib/webview.cc
+index a60ac13..2eccd1e 100644
+--- a/efl_webview/lib/webview.cc
++++ b/efl_webview/lib/webview.cc
+@@ -22,7 +22,7 @@ namespace callbacks = xwalk::webviewcallbacks;
+ const char evas_smart_xwalk_view_type[] = "Evas_Smart_Xwalk_View";
+ const Evas_Smart_Cb_Description g_smart_callbacks[] = {
+-  {callbacks::CallbackName<callbacks::LoadProgress>(), "d"},
++  {callbacks::CallbackName<callbacks::LoadingStateChanged>(), "d"},
+   {callbacks::CallbackName<callbacks::TitleChange>(), "s"},
+   {NULL, NULL}};
+diff --git a/efl_webview/lib/webview_callbacks.h b/efl_webview/lib/webview_callbacks.h
+index 241b1d6..38df9eb 100644
+--- a/efl_webview/lib/webview_callbacks.h
++++ b/efl_webview/lib/webview_callbacks.h
+@@ -12,7 +12,7 @@ namespace xwalk {
+ namespace webviewcallbacks {
+ enum CallbackType {
+-  LoadProgress,
++  LoadingStateChanged,
+   TitleChange,
+   URLChanged
+ };
+@@ -70,7 +70,7 @@ struct CallBackInfo<callbackType> {                              \
+ }
+ // Note: type 'void' means that no arguments are expected.
+-DECLARE_XWALK_VIEW_CALLBACK(LoadProgress, "load,progress", double*);
++DECLARE_XWALK_VIEW_CALLBACK(LoadingStateChanged, "loadingstate,changed", bool*);
+ DECLARE_XWALK_VIEW_CALLBACK(TitleChange, "title,changed", const char*);
+ DECLARE_XWALK_VIEW_CALLBACK(URLChanged, "url,changed", const char*);
+ }  // namespace webviewcallbacks
+diff --git a/efl_webview/public/xwalk_view.h b/efl_webview/public/xwalk_view.h
+index 680a5ab..e6f70a5 100644
+--- a/efl_webview/public/xwalk_view.h
++++ b/efl_webview/public/xwalk_view.h
+@@ -8,7 +8,7 @@
+  * The following signals (see evas_object_smart_callback_add()) are emitted:
+  *
+  * - "title,changed", const char*: title of the main frame was changed.
+- * - "load,progress", double*: load progress has changed (value from 0.0 to 1.0).
++ * - "loadingstate,changed", Eina_Bool*: loading state has changed, @c EINA_TRUE if main frame is in loading state; @c EINA_FALSE, otherwise.
+  * - "url,changed", const char*: url of the main frame was changed.
+  */
+-- 
+1.8.1.2
+
diff --git a/patchset/0022-Remove-elm-dependency-from-preserve_window_efl.patch b/patchset/0022-Remove-elm-dependency-from-preserve_window_efl.patch
new file mode 100644 (file)
index 0000000..ce28781
--- /dev/null
@@ -0,0 +1,44 @@
+From 704d403b040c6255b391a26274c723008a1f188d Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Mon, 12 Aug 2013 17:58:36 +0300
+Subject: [PATCH 22/33] Remove elm dependency from preserve_window_efl
+
+---
+ ui/gfx/preserve_window_efl.cc | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index 9c3fe3a..bed34a0 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -7,7 +7,6 @@
+ #include <Ecore.h>
+ #include <Ecore_Evas.h>
+ #include <Ecore_X.h>
+-#include <Elementary.h>
+ #include <X11/Xlib.h>
+ #include "base/logging.h"
+@@ -110,7 +109,18 @@ void evas_smart_preserve_window_smart_add(Evas_Object* o) {
+     evas_object_smart_data_set(o, smart_data);
+   }
+-  smart_data->window_ = ecore_x_window_new(elm_win_xwindow_get(o), 0, 0, 1, 1);
++  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
++  Ecore_X_Window x_window_id;
++  const char* engine_name = ecore_evas_engine_name_get(ee);
++  if (!strncmp(engine_name, "software_x11", 12)) {
++    x_window_id = ecore_evas_software_x11_window_get(ee);
++  } else if (!strncmp(engine_name, "opengl_x11", 10)) {
++    x_window_id = ecore_evas_gl_x11_window_get(ee);
++  } else {
++    LOG(FATAL) << "Unsupported Evas engine " << engine_name << "! Please add it to evas_smart_preserve_window_smart_add().";
++  }
++
++  smart_data->window_ = ecore_x_window_new(x_window_id, 0, 0, 1, 1);
+   // Do not listen to any events in this new window, otherwise they will not be
+   // propagated to the parent X window (the one which is actually interested in
+-- 
+1.8.1.2
+
diff --git a/patchset/0023-Fix-the-build-after-c109537.patch b/patchset/0023-Fix-the-build-after-c109537.patch
new file mode 100644 (file)
index 0000000..cf64f6f
--- /dev/null
@@ -0,0 +1,30 @@
+From 6be29713a38cf2c514d88855dafa06892341704f Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Mon, 12 Aug 2013 19:39:47 +0300
+Subject: [PATCH 23/33] Fix the build after c109537.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+ui/gfx/preserve_window_efl.cc:123:67: error: ‘x_window_id’ may be used
+uninitialized in this function [-Werror=maybe-uninitialized]
+---
+ ui/gfx/preserve_window_efl.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index bed34a0..827836b 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -110,7 +110,7 @@ void evas_smart_preserve_window_smart_add(Evas_Object* o) {
+   }
+   Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
+-  Ecore_X_Window x_window_id;
++  Ecore_X_Window x_window_id = 0;
+   const char* engine_name = ecore_evas_engine_name_get(ee);
+   if (!strncmp(engine_name, "software_x11", 12)) {
+     x_window_id = ecore_evas_software_x11_window_get(ee);
+-- 
+1.8.1.2
+
diff --git a/patchset/0024-Fixed-content-shell-content-rendering-crash-on-exit..patch b/patchset/0024-Fixed-content-shell-content-rendering-crash-on-exit..patch
new file mode 100644 (file)
index 0000000..c07bd36
--- /dev/null
@@ -0,0 +1,605 @@
+From 86cdb77f07cd35265d131c5648b02c14915b4674 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Tue, 13 Aug 2013 15:18:04 +0300
+Subject: [PATCH 24/33] Fixed content shell: content rendering & crash on exit.
+ Deep refactoring of PreserveWindow (as a part of crash fixing).
+
+---
+ content/shell/shell_efl.cc                         |   8 +-
+ .../shell/shell_web_contents_view_delegate_efl.cc  |   6 +-
+ efl_webview/lib/webview.h                          |   2 +-
+ ui/gfx/preserve_window_efl.cc                      | 413 ++++++++-------------
+ ui/gfx/preserve_window_efl.h                       |  14 +-
+ 5 files changed, 165 insertions(+), 278 deletions(-)
+
+diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
+index f847113..36559ca 100644
+--- a/content/shell/shell_efl.cc
++++ b/content/shell/shell_efl.cc
+@@ -65,7 +65,7 @@ void Shell::PlatformSetContents() {
+   if (headless_)
+     return;
+-  container_view_ = elm_box_add(window_);
++  container_view_ = evas_object_box_add(evas_object_evas_get(window_));
+   evas_object_size_hint_weight_set(container_view_,
+                                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+@@ -81,8 +81,6 @@ void Shell::PlatformSetContents() {
+ void Shell::SizeTo(int width, int height) {
+   content_width_ = width;
+   content_height_ = height;
+-  if (web_contents_) {
+-  }
+ }
+ void Shell::PlatformResizeSubViews() {
+@@ -111,9 +109,7 @@ void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
+ }
+ bool Shell::TakeFocus(WebContents* source, bool reverse) {
+-  DCHECK(source == web_contents_.get());
+-  elm_object_focus_next(container_view_,
+-                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
++  evas_object_focus_set(container_view_, EINA_FALSE);
+   return true;
+ }
+diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
+index 8221da0..9b95417 100644
+--- a/content/shell/shell_web_contents_view_delegate_efl.cc
++++ b/content/shell/shell_web_contents_view_delegate_efl.cc
+@@ -4,7 +4,6 @@
+ #include "content/shell/shell_web_contents_view_delegate.h"
+-#include <Elementary.h>
+ #include "base/command_line.h"
+ #include "content/public/browser/render_process_host.h"
+ #include "content/public/browser/render_view_host.h"
+@@ -51,8 +50,9 @@ WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
+ }
+ void ShellWebContentsViewDelegate::Focus() {
+-  if (native_view_)
+-    elm_object_focus_set(native_view_, EINA_TRUE);
++  if (!native_view_)
++    return;
++  evas_object_focus_set(native_view_, EINA_TRUE);
+ }
+ void ShellWebContentsViewDelegate::UpdateTitle(const string16& title) {
+diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
+index 985ef160..710d731 100644
+--- a/efl_webview/lib/webview.h
++++ b/efl_webview/lib/webview.h
+@@ -31,7 +31,7 @@ class WebView {
+   ~WebView();
+-  EAPI Evas_Object* EvasObject();
++  Evas_Object* EvasObject();
+   bool CanGoBack() const;
+   bool CanGoForward() const;
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index 827836b..6c901a7 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -17,68 +17,37 @@
+ namespace gfx {
+ namespace {
+-#define evas_smart_preserve_window_type "Evas_Smart_Preserve_Window"
+-
+-const char PRESERVE_WINDOW_MOVE[] = "preserve,moved";
+-const char PRESERVE_WINDOW_RESIZE[] = "preserve,resized";
+-const char PRESERVE_WINDOW_REPAINT[] = "preserve,repainted";
+-const Evas_Smart_Cb_Description g_smart_callbacks[] = {
+-    {PRESERVE_WINDOW_MOVE, "(ii)"},
+-    {PRESERVE_WINDOW_RESIZE, "(ii)"},
+-    {PRESERVE_WINDOW_REPAINT, "(iiii)"},
+-    {NULL, NULL}};
+-
+-enum PreserveWindowSmartEventType {
+-  PreserveWindowMoveType,
+-  PreserveWindowResizeType,
+-  PreserveWindowRepaintType,
+-};
+-
+-const char* PreserveWindowSmartEvent(PreserveWindowSmartEventType type) {
+-  switch (type) {
+-    case PreserveWindowMoveType:
+-      return PRESERVE_WINDOW_MOVE;
+-      break;
+-    case PreserveWindowResizeType:
+-      return PRESERVE_WINDOW_RESIZE;
+-      break;
+-    case PreserveWindowRepaintType:
+-      return PRESERVE_WINDOW_REPAINT;
+-      break;
+-  }
+-  NOTREACHED();
+-  return "";
+-}
++const char evas_smart_preserve_window_type[] = "Evas_Smart_Preserve_Window";
+ struct PreserveWindowData {
+-   Evas_Object_Smart_Clipped_Data base;
+-   Ecore_X_Window window_;
+-   Evas_Object* background_;
++  Evas_Object_Smart_Clipped_Data base;
++  Ecore_X_Window window;
++  Evas_Object* background;
++  gfx::PreserveWindow* self;
+ };
+ bool IsPreserveWindowEvasObject(const Evas_Object* evas_object) {
+-    DCHECK(evas_object);
++  DCHECK(evas_object);
+-    const char* evas_object_type = evas_object_type_get(evas_object);
+-    if (!evas_object_smart_type_check(evas_object,
++  const char* evas_object_type = evas_object_type_get(evas_object);
++  if (!evas_object_smart_type_check(evas_object,
+                                       evas_smart_preserve_window_type)) {
+-      LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
+-        return false;
+-    }
+-
+-    const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
+-    if (!evas_smart) {
+-        LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
+-        return false;
+-    }
++    LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
++      return false;
++  }
+-    const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
+-    if (!smart_class) {
+-      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
+-        return false;
+-    }
++  const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
++  if (!evas_smart) {
++      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
++      return false;
++  }
+-    return true;
++  const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
++  if (!smart_class) {
++    LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
++      return false;
++  }
++  return true;
+ }
+ inline PreserveWindowData* ToSmartData(Evas_Object* evas_object) {
+@@ -93,132 +62,11 @@ EVAS_SMART_SUBCLASS_NEW(evas_smart_preserve_window_type,
+                         Evas_Smart_Class,
+                         Evas_Smart_Class,
+                         evas_object_smart_clipped_class_get,
+-                        g_smart_callbacks);
+-
+-/* create and setup a new preserve window smart object's internals */
+-void evas_smart_preserve_window_smart_add(Evas_Object* o) {
+-  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
+-  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
+-  PreserveWindowData* smart_data;
+-  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
+-  if (!smart_data) {
+-    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
+-    if (!smart_data) {
+-      return;
+-    }
+-    evas_object_smart_data_set(o, smart_data);
+-  }
+-
+-  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
+-  Ecore_X_Window x_window_id = 0;
+-  const char* engine_name = ecore_evas_engine_name_get(ee);
+-  if (!strncmp(engine_name, "software_x11", 12)) {
+-    x_window_id = ecore_evas_software_x11_window_get(ee);
+-  } else if (!strncmp(engine_name, "opengl_x11", 10)) {
+-    x_window_id = ecore_evas_gl_x11_window_get(ee);
+-  } else {
+-    LOG(FATAL) << "Unsupported Evas engine " << engine_name << "! Please add it to evas_smart_preserve_window_smart_add().";
+-  }
+-
+-  smart_data->window_ = ecore_x_window_new(x_window_id, 0, 0, 1, 1);
+-
+-  // Do not listen to any events in this new window, otherwise they will not be
+-  // propagated to the parent X window (the one which is actually interested in
+-  // them).
+-  XSetWindowAttributes attributes;
+-  attributes.event_mask = NoEventMask;
+-  XChangeWindowAttributes(static_cast<Display*>(ecore_x_display_get()),
+-                          smart_data->window_, CWEventMask, &attributes);
+-
+-  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(o));
+-  evas_object_color_set(smart_data->background_, 0, 0, 0, 0);
+-  evas_object_size_hint_weight_set(smart_data->background_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+-  evas_object_focus_set(smart_data->background_, EINA_TRUE);
+-  evas_smart_preserve_window_parent_sc->add(o);
+-}
+-
+-void evas_smart_preserve_window_smart_del(Evas_Object* o) {
+-  PreserveWindowData* smart_data = ToSmartData(o);
+-  evas_object_del(smart_data->background_);
+-  ecore_x_window_free(smart_data->window_);
+-  evas_smart_preserve_window_parent_sc->del(o);
+-}
+-
+-void evas_smart_preserve_window_smart_show(Evas_Object* o) {
+-  PreserveWindowData* smart_data = ToSmartData(o);
+-  ecore_x_window_show(smart_data->window_);
+-  evas_object_show(smart_data->background_);
+-  evas_smart_preserve_window_parent_sc->show(o);
+-}
+-
+-void evas_smart_preserve_window_smart_hide(Evas_Object* o) {
+-  PreserveWindowData* smart_data = ToSmartData(o);
+-  ecore_x_window_hide(smart_data->window_);
+-  evas_object_hide(smart_data->background_);
+-  evas_smart_preserve_window_parent_sc->hide(o);
+-}
+-
+-void evas_smart_preserve_window_smart_move(Evas_Object* o,
+-                                           Evas_Coord x,
+-                                           Evas_Coord y) {
+-  Evas_Coord ox, oy;
+-  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
+-  if ((ox == x) && (oy == y))
+-    return;
+-
+-  PreserveWindowData* smart_data = ToSmartData(o);
+-  ecore_x_window_move(smart_data->window_, x, y);
+-  evas_object_move(smart_data->background_, x, y);
+-
+-  int position[2] = {x, y};
+-  evas_object_smart_callback_call(
+-      o, PRESERVE_WINDOW_MOVE, static_cast<void*>(position));
+-
+-  /* this will trigger recalculation */
+-  evas_object_smart_changed(o);
+-}
+-
+-void evas_smart_preserve_window_smart_resize(Evas_Object* o,
+-                                             Evas_Coord w,
+-                                             Evas_Coord h) {
+-  Evas_Coord ow, oh;
+-  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
+-  if ((ow == w) && (oh == h))
+-    return;
+-
+-  PreserveWindowData* smart_data = ToSmartData(o);
+-  ecore_x_window_resize(smart_data->window_, w, h);
+-  evas_object_resize(smart_data->background_, w, h);
+-
+-  int size[2] = {w, h};
+-  evas_object_smart_callback_call(
+-      o, PRESERVE_WINDOW_RESIZE, static_cast<void*>(size));
+-
+-  /* this will trigger recalculation */
+-  evas_object_smart_changed(o);
+-}
+-
+-/* act on child objects' properties, before rendering */
+-void evas_smart_preserve_window_smart_calculate(Evas_Object* o) {
+-  int dirty_rect[4] = { 0, };
+-  // FIXME: how to know dirty rect actually.
+-  evas_object_geometry_get(o, &dirty_rect[0], &dirty_rect[1], &dirty_rect[2], &dirty_rect[3]);
+-  evas_object_smart_callback_call(
+-      o, PRESERVE_WINDOW_REPAINT, static_cast<void*>(dirty_rect));
+-}
++                        0);
+ /* setting our smart interface */
+-void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
+-  /* specializing these two */
+-  sc->add = evas_smart_preserve_window_smart_add;
+-  sc->del = evas_smart_preserve_window_smart_del;
+-  sc->show = evas_smart_preserve_window_smart_show;
+-  sc->hide = evas_smart_preserve_window_smart_hide;
+-
+-  /* clipped smart object has no hook on move, resize and calculation */
+-  sc->move = evas_smart_preserve_window_smart_move;
+-  sc->resize = evas_smart_preserve_window_smart_resize;
+-  sc->calculate = evas_smart_preserve_window_smart_calculate;
++inline void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
++  PreserveWindow::InitSmartClassInterface(sc);
+ }
+ // SmartObjectEventHandler implementation.
+@@ -228,10 +76,6 @@ template <Evas_Callback_Type EventType> class SmartObjectEventHandler {
+     evas_object_event_callback_add(evas_object, EventType, HandleEvent, delegate);
+   }
+-  static void Unsubscribe(Evas_Object* evas_object) {
+-    evas_object_event_callback_del(evas_object, EventType, HandleEvent);
+-  }
+-
+   static void HandleEvent(void* data, Evas*, Evas_Object*, void* event_info);
+ };
+@@ -305,71 +149,126 @@ void SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::HandleEvent(
+   delegate->PreserveWindowHide();
+ }
+-// SmartObjectSmartHandler implementation.
+-template <PreserveWindowSmartEventType EventType> class SmartObjectSmartHandler {
+- public:
+-  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
+-    evas_object_smart_callback_add(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
+-                                   HandleEventMove, delegate);
+-    evas_object_smart_callback_add(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
+-                                   HandleEventResize, delegate);
+-    evas_object_smart_callback_add(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
+-                                   HandleEventRepaint, delegate);
++}  // namespace
++
++// static
++PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
++                                       Evas* evas) {
++  return new PreserveWindow(delegate, evas);
++}
++
++void PreserveWindow::InitSmartClassInterface(Evas_Smart_Class* sc) {
++  sc->add = HandleEvasObjectAdd;
++  sc->del = HandleEvasObjectDelete;
++  sc->show = HandleEvasObjectShow;
++  sc->hide = HandleEvasObjectHide;
++  sc->move = HandleEvasObjectMove;
++  sc->resize = HandleEvasObjectResize;
++  sc->calculate = HandleEvasObjectCalculate;  // Empty function, but we have to provide something - efl is crashing otherwise.
++}
++
++void PreserveWindow::HandleEvasObjectAdd(Evas_Object* o) {
++  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
++  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
++  PreserveWindowData* smart_data;
++  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
++  if (!smart_data) {
++    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
++    if (!smart_data) {
++      return;
++    }
++    evas_object_smart_data_set(o, smart_data);
+   }
+-  static void Unsubscribe(Evas_Object* evas_object) {
+-    evas_object_smart_callback_del(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
+-                                   HandleEventMove);
+-    evas_object_smart_callback_del(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
+-                                   HandleEventResize);
+-    evas_object_smart_callback_del(evas_object,
+-                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
+-                                   HandleEventRepaint);
++  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
++  Ecore_X_Window x_window_id = 0;
++  const char* engine_name = ecore_evas_engine_name_get(ee);
++  if (!strncmp(engine_name, "software_x11", 12)) {
++    x_window_id = ecore_evas_software_x11_window_get(ee);
++  } else if (!strncmp(engine_name, "opengl_x11", 10)) {
++    x_window_id = ecore_evas_gl_x11_window_get(ee);
++  } else {
++    LOG(FATAL) << "Unsupported Evas engine " << engine_name << "! Please add it to evas_smart_preserve_window_smart_add().";
+   }
+-  static void HandleEventMove(void* data, Evas_Object*, void* event_info);
+-  static void HandleEventResize(void* data, Evas_Object*, void* event_info);
+-  static void HandleEventRepaint(void* data, Evas_Object*, void* event_info);
+-};
++  smart_data->window = ecore_x_window_new(x_window_id, 0, 0, 1, 1);
+-template <PreserveWindowSmartEventType EventType>
+-void SmartObjectSmartHandler<EventType>::HandleEventMove(
+-    void* data, Evas_Object*, void* event_info) {
+-  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
+-  int* position = static_cast<int*>(event_info);
+-  delegate->PreserveWindowMove(gfx::Point(position[0], position[1]));
++  // Do not listen to any events in this new window, otherwise they will not be
++  // propagated to the parent X window (the one which is actually interested in
++  // them).
++  XSetWindowAttributes attributes;
++  attributes.event_mask = NoEventMask;
++  XChangeWindowAttributes(static_cast<Display*>(ecore_x_display_get()),
++                          smart_data->window, CWEventMask, &attributes);
++
++  smart_data->background = evas_object_rectangle_add(evas_object_evas_get(o));
++  evas_object_color_set(smart_data->background, 0, 0, 0, 0);
++  evas_object_size_hint_weight_set(smart_data->background, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++  evas_object_focus_set(smart_data->background, EINA_TRUE);
++  evas_smart_preserve_window_parent_sc->add(o);
+ }
+-template <PreserveWindowSmartEventType EventType>
+-void SmartObjectSmartHandler<EventType>::HandleEventResize(
+-    void* data, Evas_Object*, void* event_info) {
+-  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
+-  int* size = static_cast<int*>(event_info);
+-  delegate->PreserveWindowResize(gfx::Size(size[0], size[1]));
++void PreserveWindow::HandleEvasObjectDelete(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  evas_object_del(smart_data->background);
++  ecore_x_window_free(smart_data->window);
++
++  smart_data->self->smart_object_ = 0;  // We let PreserveWindow know that its smart_object_ does not exist any more.
++
++  evas_smart_preserve_window_parent_sc->del(o);
+ }
+-template <PreserveWindowSmartEventType EventType>
+-void SmartObjectSmartHandler<EventType>::HandleEventRepaint(
+-    void* data, Evas_Object*, void* event_info) {
+-  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
+-  int* dirty_rect = static_cast<int*>(event_info);
+-  delegate->PreserveWindowRepaint(gfx::Rect(dirty_rect[0],
+-                                            dirty_rect[1],
+-                                            dirty_rect[2],
+-                                            dirty_rect[3]));
++void PreserveWindow::HandleEvasObjectShow(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  ecore_x_window_show(smart_data->window);
++  evas_object_show(smart_data->background);
++  evas_smart_preserve_window_parent_sc->show(o);
+ }
+-}  // namespace
++void PreserveWindow::HandleEvasObjectHide(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  ecore_x_window_hide(smart_data->window);
++  evas_object_hide(smart_data->background);
++  evas_smart_preserve_window_parent_sc->hide(o);
++}
+-// static
+-PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
+-                                       Evas* evas) {
+-  return new PreserveWindow(delegate, evas);
++void PreserveWindow::HandleEvasObjectMove(Evas_Object* o,
++                                          Evas_Coord x,
++                                          Evas_Coord y) {
++  Evas_Coord ox, oy;
++  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
++  if ((ox == x) && (oy == y))
++    return;
++
++  PreserveWindowData* smart_data = ToSmartData(o);
++  ecore_x_window_move(smart_data->window, x, y);
++  evas_object_move(smart_data->background, x, y);
++
++  smart_data->self->delegate_->PreserveWindowMove(gfx::Point(x, y));
++
++  // This will trigger recalculation.
++  evas_object_smart_changed(o);
++}
++
++void PreserveWindow::HandleEvasObjectResize(Evas_Object* o,
++                                            Evas_Coord w,
++                                            Evas_Coord h) {
++  Evas_Coord ow, oh;
++  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
++  if ((ow == w) && (oh == h))
++    return;
++
++  PreserveWindowData* smart_data = ToSmartData(o);
++  ecore_x_window_resize(smart_data->window, w, h);
++  evas_object_resize(smart_data->background, w, h);
++
++  smart_data->self->delegate_->PreserveWindowResize(gfx::Size(w, h));
++
++  /* this will trigger recalculation */
++  evas_object_smart_changed(o);
++}
++
++void PreserveWindow::HandleEvasObjectCalculate(Evas_Object* o) {
+ }
+ PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
+@@ -377,49 +276,31 @@ PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
+   smart_object_ = evas_object_smart_add(evas, evas_smart_preserve_window_smart_class_new());
+   evas_object_show(smart_object_);
+-  SmartObjectSmartHandler<PreserveWindowMoveType>::Subscribe(smart_object_, delegate_);
+-  SmartObjectSmartHandler<PreserveWindowResizeType>::Subscribe(smart_object_, delegate_);
+-  SmartObjectSmartHandler<PreserveWindowRepaintType>::Subscribe(smart_object_, delegate_);
+-
+   PreserveWindowData* smart_data = ToSmartData(smart_object_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background_, delegate_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background_, delegate_);
++  smart_data->self = this;
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background, delegate_);
++  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background, delegate_);
+   // FIXME: After creation, request redraw.
+   evas_object_smart_changed(smart_object_);
+ }
+ PreserveWindow::~PreserveWindow() {
+-  SmartObjectSmartHandler<PreserveWindowMoveType>::Unsubscribe(smart_object_);
+-  SmartObjectSmartHandler<PreserveWindowResizeType>::Unsubscribe(smart_object_);
+-  SmartObjectSmartHandler<PreserveWindowRepaintType>::Unsubscribe(smart_object_);
+-
+-  PreserveWindowData* smart_data = ToSmartData(smart_object_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Unsubscribe(smart_data->background_);
+-  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Unsubscribe(smart_data->background_);
+-
+-  evas_object_del(smart_object_);
++  if (smart_object_) // smart_object_ can be deleted earlier by efl framework - via efl event loop (happens with content shell).
++    evas_object_del(smart_object_);  
+ }
+ gfx::PluginWindowHandle PreserveWindow::EmbeddedXWindow() {
+   PreserveWindowData* smart_data = ToSmartData(smart_object_);
+-  return smart_data->window_;
++  return smart_data->window;
+ }
+ }  // namespace gfx
+diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
+index 1097072..6cb48ba 100644
+--- a/ui/gfx/preserve_window_efl.h
++++ b/ui/gfx/preserve_window_efl.h
+@@ -17,15 +17,25 @@ namespace gfx {
+ class UI_EXPORT PreserveWindow {
+  public:
+-  static PreserveWindow* Create(PreserveWindowDelegate*, Evas*);
++  static PreserveWindow* Create(PreserveWindowDelegate* delegate, Evas* canvas);
+   ~PreserveWindow();
+   Evas_Object* SmartObject() const { return smart_object_; }
+   PluginWindowHandle EmbeddedXWindow();
++  static void InitSmartClassInterface(Evas_Smart_Class* smart_class);
++
+  private:
+-  PreserveWindow(PreserveWindowDelegate*, Evas*);
++  PreserveWindow(PreserveWindowDelegate* delegate, Evas* canvas);
++
++  static void HandleEvasObjectAdd(Evas_Object* evas_object);
++  static void HandleEvasObjectDelete(Evas_Object* evas_object);
++  static void HandleEvasObjectShow(Evas_Object* evas_object);
++  static void HandleEvasObjectHide(Evas_Object* evas_object);
++  static void HandleEvasObjectMove(Evas_Object*, Evas_Coord x, Evas_Coord y);
++  static void HandleEvasObjectResize(Evas_Object* evas_object, Evas_Coord width, Evas_Coord height);
++  static void HandleEvasObjectCalculate(Evas_Object* evas_object);
+   PreserveWindowDelegate* delegate_;
+   Evas_Object* smart_object_;
+-- 
+1.8.1.2
+
diff --git a/patchset/0025-Fix-key-events.patch b/patchset/0025-Fix-key-events.patch
new file mode 100644 (file)
index 0000000..9866dfd
--- /dev/null
@@ -0,0 +1,70 @@
+From 3cc152b5d3bc17e87bb41d8f1cb765bf462d3c71 Mon Sep 17 00:00:00 2001
+From: Alexander Shalamov <alexander.shalamov@intel.com>
+Date: Wed, 14 Aug 2013 11:02:13 +0300
+Subject: [PATCH 25/33] Fix key events
+
+---
+ content/browser/renderer_host/render_widget_host_view_efl.cc | 3 +++
+ ui/gfx/preserve_window_efl.cc                                | 6 ++++++
+ ui/gfx/preserve_window_efl.h                                 | 1 +
+ 3 files changed, 10 insertions(+)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index e9f3ec9..0ee06af 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -104,6 +104,7 @@ RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
+ void RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* mouse_down) {
+   // The coordinates must be relative to the view, not the root window.
++  PreserveWindowFocusIn();
+   int view_x, view_y;
+   evas_object_geometry_get(preserve_window_->SmartObject(),
+                            &view_x, &view_y, NULL, NULL);
+@@ -155,12 +156,14 @@ void RenderWidgetHostViewEfl::PreserveWindowFocusIn() {
+   host_->GotFocus();
+   host_->SetActive(true);
++  preserve_window_->SetFocus(true);
+ }
+ void RenderWidgetHostViewEfl::PreserveWindowFocusOut() {
+   if (host_ && !IsShowingContextMenu()) {
+     host_->SetActive(false);
+     host_->Blur();
++    preserve_window_->SetFocus(false);
+   }
+ }
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index 6c901a7..2d783e3 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -298,6 +298,12 @@ PreserveWindow::~PreserveWindow() {
+     evas_object_del(smart_object_);  
+ }
++void PreserveWindow::SetFocus(bool focus)
++{
++  PreserveWindowData* smart_data = ToSmartData(smart_object_);
++  evas_object_focus_set(smart_data->background, focus);
++}
++
+ gfx::PluginWindowHandle PreserveWindow::EmbeddedXWindow() {
+   PreserveWindowData* smart_data = ToSmartData(smart_object_);
+   return smart_data->window;
+diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
+index 6cb48ba..e22f508 100644
+--- a/ui/gfx/preserve_window_efl.h
++++ b/ui/gfx/preserve_window_efl.h
+@@ -23,6 +23,7 @@ class UI_EXPORT PreserveWindow {
+   Evas_Object* SmartObject() const { return smart_object_; }
+   PluginWindowHandle EmbeddedXWindow();
++  void SetFocus(bool focus);
+   static void InitSmartClassInterface(Evas_Smart_Class* smart_class);
+-- 
+1.8.1.2
+
diff --git a/patchset/0026-Example-app-code-clean-up.patch b/patchset/0026-Example-app-code-clean-up.patch
new file mode 100644 (file)
index 0000000..cde7d8a
--- /dev/null
@@ -0,0 +1,410 @@
+From 78c7d4c7b7f3737375643238d5cfaa84ca2e7d07 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Wed, 14 Aug 2013 15:16:12 +0300
+Subject: [PATCH 26/33] Example app code clean-up.
+
+---
+ efl_webview/efl_webview.gyp  |   2 +-
+ efl_webview/examples/main.c  | 179 ++++++++++++++++++++++++++++++++++++++++
+ efl_webview/examples/main.cc | 190 -------------------------------------------
+ 3 files changed, 180 insertions(+), 191 deletions(-)
+ create mode 100644 efl_webview/examples/main.c
+ delete mode 100644 efl_webview/examples/main.cc
+
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index c71eb7b..630102b 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -114,7 +114,7 @@
+         '..',
+       ],
+       'sources': [
+-        'examples/main.cc',
++        'examples/main.c',
+       ],
+       'conditions': [
+         ['toolkit_uses_efl == 1', {
+diff --git a/efl_webview/examples/main.c b/efl_webview/examples/main.c
+new file mode 100644
+index 0000000..7f18e8d
+--- /dev/null
++++ b/efl_webview/examples/main.c
+@@ -0,0 +1,179 @@
++// Copyright (c) 2013 Intel Corporation. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++#include <Ecore.h>
++#include <Ecore_Evas.h>
++#include <Elementary.h>
++
++#include "efl_webview/public/xwalk_main.h"
++#include "efl_webview/public/xwalk_view.h"
++
++static const char APP_NAME[] = "EFL WebView Example";
++
++static int window_width = 800;
++static int window_height = 600;
++
++static void
++on_back_button_clicked(void *user_data, Evas_Object *back_button,
++                       void *event_info)
++{
++  xwalk_view_back((Evas_Object*)user_data);
++}
++
++static void
++on_forward_button_clicked(void *user_data, Evas_Object *forward_button,
++                          void *event_info)
++{
++  xwalk_view_forward((Evas_Object*)user_data);
++}
++
++static void
++on_reload_button_clicked(void *user_data, Evas_Object *forward_button,
++                         void *event_info)
++{
++  xwalk_view_reload((Evas_Object*)user_data);
++}
++
++static void
++on_url_entry_activated(void *user_data, Evas_Object *url_entry,
++                       void *event_info)
++{
++  const char* url = elm_entry_entry_get(url_entry);
++  xwalk_view_url_set((Evas_Object*)user_data, url);
++}
++
++static void
++on_title_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
++{
++  const char *title = (const char *)event_info;
++  elm_win_title_set((Evas_Object*)user_data, title);
++}
++
++static void
++on_url_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
++{
++  char *url = elm_entry_utf8_to_markup((const char *)event_info);
++  elm_entry_entry_set((Evas_Object*)user_data, url);
++  free(url);
++}
++
++static void
++on_loadingstate_changed(void *user_data,
++                        Evas_Object *xwalk_view,
++                        void *event_info)
++{
++  elm_progressbar_pulse((Evas_Object*)user_data, *(Eina_Bool*)event_info);
++}
++
++static void window_create()
++{
++  /* Create elementary window */
++  Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window",
++                                                      APP_NAME);
++  elm_win_autodel_set(elm_window, EINA_TRUE);
++  elm_object_focus_allow_set(elm_window, EINA_TRUE);
++
++  /* Create vertical layout that holds navigation bar and webview area */
++  Evas_Object* vertical_layout = elm_box_add(elm_window);
++  elm_box_padding_set(vertical_layout, 0, 4);
++  evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
++  elm_win_resize_object_add(elm_window, vertical_layout);
++  evas_object_show(vertical_layout);
++
++  /* Create horizontal layout for navigation bar */
++  Evas_Object* horizontal_layout = elm_box_add(elm_window);
++  elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
++  evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
++  evas_object_size_hint_align_set(horizontal_layout, EVAS_HINT_FILL, 0.0);
++  elm_box_pack_end(vertical_layout, horizontal_layout);
++  evas_object_show(horizontal_layout);
++
++  /* Create back button */
++  Evas_Object* back_button = elm_button_add(elm_window);
++  elm_object_text_set(back_button, "BACK");
++  elm_box_pack_end(horizontal_layout, back_button);
++  evas_object_show(back_button);
++
++  /* Create forward button */
++  Evas_Object* forward_button = elm_button_add(elm_window);
++  elm_object_text_set(forward_button, "FORWARD");
++  elm_box_pack_end(horizontal_layout, forward_button);
++  evas_object_show(forward_button);
++
++  /* Create reload button */
++  Evas_Object* reload_button = elm_button_add(elm_window);
++  elm_object_text_set(reload_button, "RELOAD");
++  elm_box_pack_end(horizontal_layout, reload_button);
++  evas_object_show(reload_button);
++
++  /* Create url entry widget */
++  Evas_Object* url_entry = elm_entry_add(elm_window);
++  elm_entry_single_line_set(url_entry, EINA_TRUE);
++  elm_entry_scrollable_set(url_entry, EINA_TRUE);
++  elm_entry_cnp_mode_set(url_entry, ELM_CNP_MODE_PLAINTEXT);
++  elm_entry_scrollbar_policy_set(url_entry, ELM_SCROLLER_POLICY_OFF,
++                                 ELM_SCROLLER_POLICY_OFF);
++  elm_entry_text_style_user_push(url_entry, "DEFAULT='font_size=16'");
++  evas_object_size_hint_weight_set(url_entry, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(url_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
++  elm_box_pack_end(horizontal_layout, url_entry);
++  evas_object_show(url_entry);
++
++  Evas_Object* progress_bar = elm_progressbar_add(elm_window);
++  elm_progressbar_span_size_set(progress_bar, 10);
++  elm_progressbar_pulse_set(progress_bar, EINA_TRUE);
++  elm_progressbar_unit_format_set(progress_bar, NULL);
++  evas_object_size_hint_align_set(progress_bar, EVAS_HINT_FILL, 1);
++  evas_object_size_hint_weight_set(progress_bar, 0.01, EVAS_HINT_EXPAND);
++  elm_box_pack_end(horizontal_layout, progress_bar);
++  evas_object_show(progress_bar);
++
++  /* Create WebView */
++  Evas_Object* web_view = xwalk_view_add(evas_object_evas_get(elm_window));
++  evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND,
++                                   EVAS_HINT_EXPAND);
++  evas_object_size_hint_align_set(web_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
++  elm_box_pack_end(vertical_layout, web_view);
++  elm_object_focus_set(web_view, EINA_TRUE);
++  evas_object_show(web_view);
++
++  evas_object_smart_callback_add(back_button, "clicked",
++                                 on_back_button_clicked, web_view);
++  evas_object_smart_callback_add(forward_button, "clicked",
++                                 on_forward_button_clicked, web_view);
++  evas_object_smart_callback_add(reload_button, "clicked",
++                                 on_reload_button_clicked, web_view);
++  evas_object_smart_callback_add(url_entry, "activated",
++                                 on_url_entry_activated, web_view);
++
++  evas_object_smart_callback_add(web_view, "title,changed",
++                                 on_title_changed, elm_window);
++  evas_object_smart_callback_add(web_view, "url,changed",
++                                 on_url_changed, url_entry);
++  evas_object_smart_callback_add(web_view, "loadingstate,changed",
++                                 on_loadingstate_changed, progress_bar);
++
++  evas_object_resize(elm_window, window_width, window_height);
++  evas_object_show(elm_window);
++}
++
++int main(int argc, char *argv[])
++{
++  // FIXME: Handle chrome command line and url.
++  // It is needed only in development stage.
++  xwalk_init(argc, argv);
++
++  elm_init(argc, argv);
++
++  elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
++
++  window_create();
++
++  elm_run();
++  elm_shutdown();
++
++  return 0;
++}
+diff --git a/efl_webview/examples/main.cc b/efl_webview/examples/main.cc
+deleted file mode 100644
+index c0cbf4b..0000000
+--- a/efl_webview/examples/main.cc
++++ /dev/null
+@@ -1,190 +0,0 @@
+-// Copyright (c) 2013 Intel Corporation. All rights reserved.
+-// Use of this source code is governed by a BSD-style license that can be
+-// found in the LICENSE file.
+-
+-#include <Ecore.h>
+-#include <Ecore_Evas.h>
+-#include <Elementary.h>
+-
+-#include "efl_webview/lib/process_main.h"
+-#include "efl_webview/lib/webview.h"
+-#include "efl_webview/public/xwalk_main.h"
+-#include "efl_webview/public/xwalk_view.h"
+-
+-static const char APP_NAME[] = "EFL WebView Example";
+-
+-static int window_width = 800;
+-static int window_height = 600;
+-
+-static void
+-on_back_button_clicked(void *user_data, Evas_Object *back_button,
+-                       void *event_info)
+-{
+-  xwalk_view_back((Evas_Object*)user_data);
+-}
+-
+-static void
+-on_forward_button_clicked(void *user_data, Evas_Object *forward_button,
+-                          void *event_info)
+-{
+-  xwalk_view_forward((Evas_Object*)user_data);
+-}
+-
+-static void
+-on_reload_button_clicked(void *user_data, Evas_Object *forward_button,
+-                         void *event_info)
+-{
+-  xwalk_view_reload((Evas_Object*)user_data);
+-}
+-
+-static void
+-on_url_entry_activated(void *user_data, Evas_Object *url_entry,
+-                       void *event_info)
+-{
+-  const char* url = elm_entry_entry_get(url_entry);
+-  xwalk_view_url_set((Evas_Object*)user_data, url);
+-}
+-
+-static void
+-on_progress(void *user_data, Evas_Object *xwalk_view, void *event_info)
+-{
+-  /* double progress = *(double *)event_info; */
+-  /* FIXME : implement. */
+-}
+-
+-static void
+-on_title_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
+-{
+-    const char *title = (const char *)event_info;
+-    elm_win_title_set((Evas_Object*)user_data, title);
+-}
+-
+-static void
+-on_url_changed(void *user_data, Evas_Object *xwalk_view, void *event_info)
+-{
+-    char *url = elm_entry_utf8_to_markup((const char *)event_info);
+-    elm_entry_entry_set((Evas_Object*)user_data, url);
+-    free(url);
+-}
+-
+-static void
+-on_loadingstate_changed(void *user_data,
+-                        Evas_Object *xwalk_view,
+-                        void *event_info)
+-{
+-  elm_progressbar_pulse((Evas_Object*)user_data, *(bool*)event_info);
+-}
+-
+-static void window_create()
+-{
+-  /* Create elementary window */
+-  Evas_Object* elm_window = elm_win_util_standard_add("efl-webview-window",
+-                                                      APP_NAME);
+-  elm_win_autodel_set(elm_window, EINA_TRUE);
+-  elm_object_focus_allow_set(elm_window, EINA_TRUE);
+-
+-  /* Create vertical layout that holds navigation bar and webview area */
+-  Evas_Object* vertical_layout = elm_box_add(elm_window);
+-  elm_box_padding_set(vertical_layout, 0, 4);
+-  evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND,
+-                                   EVAS_HINT_EXPAND);
+-  elm_win_resize_object_add(elm_window, vertical_layout);
+-  evas_object_show(vertical_layout);
+-
+-  /* Create horizontal layout for navigation bar */
+-  Evas_Object* horizontal_layout = elm_box_add(elm_window);
+-  elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
+-  evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
+-  evas_object_size_hint_align_set(horizontal_layout, EVAS_HINT_FILL, 0.0);
+-  elm_box_pack_end(vertical_layout, horizontal_layout);
+-  evas_object_show(horizontal_layout);
+-
+-  /* Create back button */
+-  Evas_Object* back_button = elm_button_add(elm_window);
+-  elm_object_text_set(back_button, "BACK");
+-  elm_box_pack_end(horizontal_layout, back_button);
+-  evas_object_show(back_button);
+-
+-  /* Create forward button */
+-  Evas_Object* forward_button = elm_button_add(elm_window);
+-  elm_object_text_set(forward_button, "FORWARD");
+-  elm_box_pack_end(horizontal_layout, forward_button);
+-  evas_object_show(forward_button);
+-
+-  /* Create reload button */
+-  Evas_Object* reload_button = elm_button_add(elm_window);
+-  elm_object_text_set(reload_button, "RELOAD");
+-  elm_box_pack_end(horizontal_layout, reload_button);
+-  evas_object_show(reload_button);
+-
+-  /* Create url entry widget */
+-  Evas_Object* url_entry = elm_entry_add(elm_window);
+-  elm_entry_single_line_set(url_entry, EINA_TRUE);
+-  elm_entry_scrollable_set(url_entry, EINA_TRUE);
+-  elm_entry_cnp_mode_set(url_entry, ELM_CNP_MODE_PLAINTEXT);
+-  elm_entry_scrollbar_policy_set(url_entry, ELM_SCROLLER_POLICY_OFF,
+-                                 ELM_SCROLLER_POLICY_OFF);
+-  elm_entry_text_style_user_push(url_entry, "DEFAULT='font_size=16'");
+-  evas_object_size_hint_weight_set(url_entry, EVAS_HINT_EXPAND,
+-                                   EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(url_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+-  elm_box_pack_end(horizontal_layout, url_entry);
+-  evas_object_show(url_entry);
+-
+-  Evas_Object* progress_bar = elm_progressbar_add(elm_window);
+-  elm_progressbar_span_size_set(progress_bar, 10);
+-  elm_progressbar_pulse_set(progress_bar, EINA_TRUE);
+-  elm_progressbar_unit_format_set(progress_bar, NULL);
+-  evas_object_size_hint_align_set(progress_bar, EVAS_HINT_FILL, 1);
+-  evas_object_size_hint_weight_set(progress_bar, 0.01, EVAS_HINT_EXPAND);
+-  elm_box_pack_end(horizontal_layout, progress_bar);
+-  evas_object_show(progress_bar);
+-
+-  /* Create WebView */
+-  Evas_Object* web_view = xwalk_view_add(evas_object_evas_get(elm_window));
+-  evas_object_size_hint_weight_set(web_view, EVAS_HINT_EXPAND,
+-                                   EVAS_HINT_EXPAND);
+-  evas_object_size_hint_align_set(web_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
+-  elm_box_pack_end(vertical_layout, web_view);
+-  elm_object_focus_set(web_view, EINA_TRUE);
+-  evas_object_show(web_view);
+-
+-  evas_object_smart_callback_add(back_button, "clicked",
+-                                 on_back_button_clicked, web_view);
+-  evas_object_smart_callback_add(forward_button, "clicked",
+-                                 on_forward_button_clicked, web_view);
+-  evas_object_smart_callback_add(reload_button, "clicked",
+-                                 on_reload_button_clicked, web_view);
+-  evas_object_smart_callback_add(url_entry, "activated",
+-                                 on_url_entry_activated, web_view);
+-
+-  evas_object_smart_callback_add(web_view, "load,progress",
+-                                 on_progress, elm_window);
+-  evas_object_smart_callback_add(web_view, "title,changed",
+-                                 on_title_changed, elm_window);
+-  evas_object_smart_callback_add(web_view, "url,changed",
+-                                 on_url_changed, url_entry);
+-  evas_object_smart_callback_add(web_view, "loadingstate,changed",
+-                                 on_loadingstate_changed, progress_bar);
+-
+-  evas_object_resize(elm_window, window_width, window_height);
+-  evas_object_show(elm_window);
+-}
+-
+-int main(int argc, char *argv[])
+-{
+-  // FIXME: Handle chrome command line and url.
+-  // It is needed only in development stage.
+-  xwalk_init(argc, argv);
+-
+-  elm_init(argc, argv);
+-
+-  elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+-
+-  window_create();
+-
+-  elm_run();
+-  elm_shutdown();
+-
+-  return 0;
+-}
+-- 
+1.8.1.2
+
diff --git a/patchset/0027-Always-build-the-efl_webview-target-as-a-shared-libr.patch b/patchset/0027-Always-build-the-efl_webview-target-as-a-shared-libr.patch
new file mode 100644 (file)
index 0000000..b19049c
--- /dev/null
@@ -0,0 +1,33 @@
+From 2b1967f2e23de6675719dd9c06f9280eb838bdca Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Mon, 12 Aug 2013 18:06:31 +0300
+Subject: [PATCH 27/33] Always build the efl_webview target as a shared
+ library.
+
+In the vast majority of the time, people are interested in using
+libefl_webview.so as a shared library instead of a static archive.
+
+Chromium's `component' variable specifies whether one wants to build all
+libraries as shared or static; in our case, we want to build all libraries
+as static, _except_ for the final libefl_webview.so, which should always be
+shared.
+---
+ efl_webview/efl_webview.gyp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index 630102b..93de1f3 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -14,7 +14,7 @@
+   'targets': [
+     {
+       'target_name': 'efl_webview',
+-      'type': '<(component)',
++      'type': 'shared_library',
+       'variables': {
+         'chromium_code': 1,
+       },
+-- 
+1.8.1.2
+
diff --git a/patchset/0028-Remove-a-few-unused-variables-from-the-efl_webview-g.patch b/patchset/0028-Remove-a-few-unused-variables-from-the-efl_webview-g.patch
new file mode 100644 (file)
index 0000000..714845d
--- /dev/null
@@ -0,0 +1,26 @@
+From a4edec502bd8821c1d33abdf17b5a387784caf9b Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Mon, 12 Aug 2013 18:19:27 +0300
+Subject: [PATCH 28/33] Remove a few unused variables from the efl_webview gyp
+ file.
+
+---
+ efl_webview/efl_webview.gyp | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/efl_webview/efl_webview.gyp b/efl_webview/efl_webview.gyp
+index 93de1f3..58a9f77 100644
+--- a/efl_webview/efl_webview.gyp
++++ b/efl_webview/efl_webview.gyp
+@@ -1,8 +1,5 @@
+ {
+   'variables': {
+-    'efl_webview_product_name': 'EFL WebView',
+-    # TODO: define efl webview version format.
+-    'cameo_version': '0.28.0.1',
+     'conditions': [
+       ['OS=="linux"', {
+        'use_custom_freetype%': 1,
+-- 
+1.8.1.2
+
diff --git a/patchset/0029-packaging-Add-a-.spec-file-for-crosswalk-webview.patch b/patchset/0029-packaging-Add-a-.spec-file-for-crosswalk-webview.patch
new file mode 100644 (file)
index 0000000..4f1f93b
--- /dev/null
@@ -0,0 +1,244 @@
+From 38fff363c0169c006ee437c958af03e661a72fdb Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Mon, 12 Aug 2013 19:06:14 +0300
+Subject: [PATCH 29/33] packaging: Add a .spec file for crosswalk-webview.
+
+It is heavily based on the .spec file we have for crosswalk itself (since
+most of the job revolves around building Blink and parts of Chromium).
+
+We also produce a -demo and a -devel package; the former contains the
+efl_webview_example application and the latter has the public development
+headers.
+---
+ .../crosswalk-webview-do-not-look-for-gtk2.patch   |  22 +++
+ ...osswalk-webview-look-for-pvr-libGLESv2.so.patch |  17 +++
+ packaging/crosswalk-webview.manifest               |   5 +
+ packaging/crosswalk-webview.spec                   | 149 +++++++++++++++++++++
+ 4 files changed, 193 insertions(+)
+ create mode 100644 packaging/crosswalk-webview-do-not-look-for-gtk2.patch
+ create mode 100644 packaging/crosswalk-webview-look-for-pvr-libGLESv2.so.patch
+ create mode 100644 packaging/crosswalk-webview.manifest
+ create mode 100644 packaging/crosswalk-webview.spec
+
+diff --git a/packaging/crosswalk-webview-do-not-look-for-gtk2.patch b/packaging/crosswalk-webview-do-not-look-for-gtk2.patch
+new file mode 100644
+index 0000000..db1e234
+--- /dev/null
++++ b/packaging/crosswalk-webview-do-not-look-for-gtk2.patch
+@@ -0,0 +1,22 @@
++Author: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
++
++Since there is no GTK+2 package for Tizen 2.1 Mobile and we do not use it
++anyway, there should be no need to look for GTK+2 at all.
++
++Upstreaming this patch depends on a hard GTK+2 dependency on
++remoting/remoting.gyp being removed in chromium. It does not affect crosswalk
++because we do not have any dependency on remoting.gyp.
++
++Upstream patch: https://codereview.chromium.org/19531008
++Depends on:     https://code.google.com/p/chromium/issues/detail?id=247213
++--- src/build/linux/system.gyp
+++++ src/build/linux/system.gyp
++@@ -28,7 +28,7 @@
++         'use_system_ssl%': 1,
++       },
++     }],
++-    [ 'chromeos==0', {
+++    [ 'chromeos==0 and toolkit_uses_gtk==1', {
++       # Hide GTK and related dependencies for Chrome OS, so they won't get
++       # added back to Chrome OS. Don't try to use GTK on Chrome OS.
++       'targets': [
+diff --git a/packaging/crosswalk-webview-look-for-pvr-libGLESv2.so.patch b/packaging/crosswalk-webview-look-for-pvr-libGLESv2.so.patch
+new file mode 100644
+index 0000000..3fad305
+--- /dev/null
++++ b/packaging/crosswalk-webview-look-for-pvr-libGLESv2.so.patch
+@@ -0,0 +1,17 @@
++Author: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
++
++The PowerVR GL implementation used in Tizen Mobile 2.1 installs libGLESv2.so.1,
++not .2. Adjust the library being looked for, otherwise the detection will fail.
++
++Not upstreamable.
++--- src/ui/gl/gl_implementation_x11.cc
+++++ src/ui/gl/gl_implementation_x11.cc
++@@ -139,7 +139,7 @@ bool InitializeGLBindings(GLImplementation implementation) {
++       break;
++     }
++     case kGLImplementationEGLGLES2: {
++-      base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so.2");
+++      base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so.1");
++       if (!gles_library)
++         return false;
++       base::NativeLibrary egl_library = LoadLibrary("libEGL.so.1");
+\ No newline at end of file
+diff --git a/packaging/crosswalk-webview.manifest b/packaging/crosswalk-webview.manifest
+new file mode 100644
+index 0000000..09fdd97
+--- /dev/null
++++ b/packaging/crosswalk-webview.manifest
+@@ -0,0 +1,5 @@
++<manifest>
++ <request>
++    <domain name="_"/>
++ </request>
++</manifest>
+\ No newline at end of file
+diff --git a/packaging/crosswalk-webview.spec b/packaging/crosswalk-webview.spec
+new file mode 100644
+index 0000000..a48eafa
+--- /dev/null
++++ b/packaging/crosswalk-webview.spec
+@@ -0,0 +1,149 @@
++Name:           crosswalk-webview
++Version:        0.1
++Release:        0
++Summary:        EFL WebView based on the Crosswalk project
++License:        BSD-3-Clause    # TODO(rakuco): multiple licenses
++Group:          Applications/Internet
++URL:            http://www.crosswalk-project.org
++Source0:        %{name}-%{version}.tar
++Source1001:     %{name}.manifest
++Patch1:         %{name}-do-not-look-for-gtk2.patch
++Patch2:         %{name}-look-for-pvr-libGLESv2.so.patch
++
++BuildRequires:  bison
++BuildRequires:  bzip2-devel
++BuildRequires:  expat-devel
++BuildRequires:  flex
++BuildRequires:  gperf
++BuildRequires:  libasound-devel
++BuildRequires:  python
++BuildRequires:  python-xml
++BuildRequires:  perl
++BuildRequires:  which
++BuildRequires:  pkgconfig(cairo)
++BuildRequires:  pkgconfig(dbus-1)
++BuildRequires:  pkgconfig(ecore)
++BuildRequires:  pkgconfig(ecore-evas)
++BuildRequires:  pkgconfig(eina)
++BuildRequires:  pkgconfig(elementary)
++BuildRequires:  pkgconfig(evas)
++BuildRequires:  pkgconfig(fontconfig)
++BuildRequires:  pkgconfig(freetype2)
++BuildRequires:  pkgconfig(gles20)
++BuildRequires:  pkgconfig(glib-2.0)
++BuildRequires:  pkgconfig(icu-i18n)
++BuildRequires:  pkgconfig(libexif)
++BuildRequires:  pkgconfig(libpci)
++BuildRequires:  pkgconfig(libpulse)
++BuildRequires:  pkgconfig(libudev)
++BuildRequires:  pkgconfig(libxml-2.0)
++BuildRequires:  pkgconfig(libxslt)
++BuildRequires:  pkgconfig(nspr)
++BuildRequires:  pkgconfig(nss)
++BuildRequires:  pkgconfig(pango)
++BuildRequires:  pkgconfig(x11)
++BuildRequires:  pkgconfig(xcomposite)
++BuildRequires:  pkgconfig(xcursor)
++BuildRequires:  pkgconfig(xdamage)
++BuildRequires:  pkgconfig(xext)
++BuildRequires:  pkgconfig(xfixes)
++BuildRequires:  pkgconfig(xi)
++BuildRequires:  pkgconfig(xrandr)
++BuildRequires:  pkgconfig(xrender)
++BuildRequires:  pkgconfig(xscrnsaver)
++BuildRequires:  pkgconfig(xt)
++BuildRequires:  pkgconfig(xtst)
++
++%description
++An implementation of a WebView toolkit component for EFL applications based on the
++Crosswalk project.
++
++%package demo
++Summary:        EFL WebView based on the Crosswalk project (demo programs)
++License:        BSD-3-Clause    # TODO(rakuco): multiple licenses
++Group:          Applications/Internet
++Url:            http://www.crosswalk-project.org
++Requires:       %{name} = %{version}
++
++%description demo
++Demo utilities for the crosswalk-webview library.
++
++crosswalk-webview is an implementation of a WebView toolkit component for EFL
++applications based on the Crosswalk project.
++
++%package devel
++Summary:        EFL WebView based on the Crosswalk project (development files)
++License:        BSD-3-Clause    # TODO(rakuco): multiple licenses
++Group:          Development/Libraries
++Url:            http://www.crosswalk-project.org
++Requires:       %{name} = %{version}
++
++%description devel
++This package countains all include files, libraries, configuration files needed
++for compiling applications which use the crosswalk-webview library.
++
++crosswalk-webview is an implementation of a WebView toolkit component for EFL
++applications based on the Crosswalk project.
++
++%prep
++%setup -q
++
++cp %{SOURCE1001} .
++
++cp -a src/AUTHORS AUTHORS
++cp -a src/LICENSE LICENSE
++
++%patch1
++
++# TODO(rakuco): Only needed for ia32 on Tizen 2.x.
++%patch2
++
++%build
++
++# For ffmpeg on ia32. The original CFLAGS set by the gyp and config files in
++# src/third_party/ffmpeg already pass -O2 -fomit-frame-pointer, but Tizen's
++# CFLAGS end up appending -fno-omit-frame-pointer. See http://crbug.com/37246
++export CFLAGS=`echo $CFLAGS | sed s,-fno-omit-frame-pointer,,g`
++
++export GYP_GENERATORS='make'
++./src/build/gyp_chromium src/efl_webview/efl_webview.gyp \
++-Ddisable_nacl=1 \
++-Duse_cups=0 \
++-Duse_gconf=0 \
++-Duse_kerberos=0 \
++-Duse_system_bzip2=1 \
++-Duse_system_icu=1 \
++-Duse_system_libexif=1 \
++-Duse_system_libxml=1 \
++-Duse_system_nspr=1 \
++-Duse_gnome_keyring=0
++
++make %{?_smp_mflags} -C src BUILDTYPE=Release efl_webview_example
++
++%install
++# Binaries.
++install -m 755 -D src/out/Release/efl_process %{buildroot}%{_bindir}/efl_process
++install -m 755 -D src/out/Release/efl_webview_example %{buildroot}%{_bindir}/efl_webview_example
++
++# Development headers.
++mkdir -p %{buildroot}%{_includedir}/crosswalk-webview/public/
++install -m 644 src/efl_webview/public/*.h %{buildroot}%{_includedir}/crosswalk-webview/public/
++
++# Supporting libraries and resources.
++# Note that a single libefl_webview.so is produced by gyp, contrary to
++# the recommended practice of producing versioned shared libraries.
++install -D src/out/Release/lib.target/libefl_webview.so %{buildroot}%{_libdir}/libefl_webview.so
++
++%post -p /sbin/ldconfig
++%postun -p /sbin/ldconfig
++
++%files
++%manifest %{name}.manifest
++%{_bindir}/efl_process
++%{_libdir}/libefl_webview.so
++
++%files devel
++%{_includedir}/crosswalk-webview/*
++
++%files demo
++%{_bindir}/efl_webview_example
+-- 
+1.8.1.2
+
diff --git a/patchset/0030-Remove-outdated-TODO.patch b/patchset/0030-Remove-outdated-TODO.patch
new file mode 100644 (file)
index 0000000..16e73a2
--- /dev/null
@@ -0,0 +1,27 @@
+From 84827b0073c7ff0b8959d7b4cfbf42cd15be457b Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Wed, 14 Aug 2013 17:57:15 +0300
+Subject: [PATCH 30/33] Remove outdated TODO.
+
+Hardcoding efl_process' name is just fine, there is no need to be able to
+change it via the build system.
+---
+ efl_webview/lib/web_runtime_context.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/efl_webview/lib/web_runtime_context.cc b/efl_webview/lib/web_runtime_context.cc
+index 005a6d2..ffceaec 100644
+--- a/efl_webview/lib/web_runtime_context.cc
++++ b/efl_webview/lib/web_runtime_context.cc
+@@ -35,7 +35,7 @@ namespace xwalk {
+ namespace {
+ WebRuntimeContext* g_context = 0;
+-// TODO: it should be passed via build system.
++
+ const char g_sub_process_name[] = "efl_process";
+ void SubprocessPathInit() {
+-- 
+1.8.1.2
+
diff --git a/patchset/0031-Be-more-flexible-in-the-way-we-look-for-efl_process.patch b/patchset/0031-Be-more-flexible-in-the-way-we-look-for-efl_process.patch
new file mode 100644 (file)
index 0000000..a12f493
--- /dev/null
@@ -0,0 +1,91 @@
+From f15c42e99c2a4c3d7404959a033a852df3516d55 Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Date: Fri, 16 Aug 2013 14:06:52 +0300
+Subject: [PATCH 31/33] Be more flexible in the way we look for "efl_process".
+
+The existing code always expected the "efl_process" helper process to be in
+the same directory as the program being run.
+
+This obviously breaks horribly when "efl_process" is installed in a system
+location and one is developing a new application in another directory.
+
+Mitigate the problem by first looking for the helper process in the
+application's current directory and then checking /usr/bin.
+
+This is only a slight bit more portable, but gyp does not have the notions
+of "install target" and "installation directories", so we cannot also check
+for a location where we always expect the executable to be.
+---
+ efl_webview/lib/web_runtime_context.cc | 40 +++++++++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/efl_webview/lib/web_runtime_context.cc b/efl_webview/lib/web_runtime_context.cc
+index ffceaec..48f5f7c 100644
+--- a/efl_webview/lib/web_runtime_context.cc
++++ b/efl_webview/lib/web_runtime_context.cc
+@@ -21,6 +21,7 @@
+ #include "base/base_paths.h"
+ #include "base/command_line.h"
++#include "base/file_util.h"
+ #include "base/path_service.h"
+ #include "content/public/app/content_main_runner.h"
+ #include "content/public/browser/browser_main_runner.h"
+@@ -38,17 +39,36 @@ WebRuntimeContext* g_context = 0;
+ const char g_sub_process_name[] = "efl_process";
+-void SubprocessPathInit() {
+-  base::FilePath current_directory;
+-  CHECK(PathService::Get(base::FILE_EXE, &current_directory));
+-  current_directory = current_directory.DirName();
+-
+-  // TODO: use more elegant way.
+-  base::FilePath subprocess_path(
+-      current_directory.value() + "/" + g_sub_process_name);
++base::FilePath SubProcessPath() {
++  // We look for "efl_process" in two places:
++  // 1. The running binary's directory.
++  // 2. A hardcoded /usr/bin.
++  // TODO: This is not portable and unfriendly to packagers, but gyp's lack of
++  // an "install" target (and therefore of destination paths) makes portability
++  // difficult.
++  base::FilePath sub_process_path_current;
++  CHECK(PathService::Get(base::DIR_EXE, &sub_process_path_current));
++  base::FilePath sub_process_path_fallback("/usr/bin");
++
++  sub_process_path_current =
++      sub_process_path_current.Append(g_sub_process_name);
++  sub_process_path_fallback =
++      sub_process_path_fallback.Append(g_sub_process_name);
++
++  if (file_util::PathExists(sub_process_path_current))
++    return sub_process_path_current;
++  else if (file_util::PathExists(sub_process_path_fallback))
++    return sub_process_path_fallback;
++
++  LOG(FATAL) << "No process called '" << g_sub_process_name
++             << "' could not be found on the system.";
++  return base::FilePath();
++}
++void SubProcessPathInit() {
++  static const base::FilePath& sub_process_path = SubProcessPath();
+   CommandLine::ForCurrentProcess()->
+-      AppendSwitchPath(switches::kBrowserSubprocessPath, subprocess_path);
++      AppendSwitchPath(switches::kBrowserSubprocessPath, sub_process_path);
+ }
+ base::MessagePump* MessagePumpFactory()
+@@ -71,7 +91,7 @@ WebRuntimeContext::WebRuntimeContext() {
+     runner->Initialize(0, 0, new ContentMainDelegateXWalk);
+   }
+-  SubprocessPathInit();
++  SubProcessPathInit();
+   static content::BrowserMainRunner *browserRunner = 0;
+   if (!browserRunner) {
+-- 
+1.8.1.2
+
diff --git a/patchset/0032-Obviate-device-scale-factor-problem.patch b/patchset/0032-Obviate-device-scale-factor-problem.patch
new file mode 100644 (file)
index 0000000..159d714
--- /dev/null
@@ -0,0 +1,64 @@
+From e0a14f54cc9874faa19b1fbe930e2c40ee044055 Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Tue, 10 Sep 2013 13:30:41 +0300
+Subject: [PATCH 32/33] Obviate device scale factor problem.
+
+---
+ content/browser/renderer_host/window_utils_efl.cc | 33 +++--------------------
+ 1 file changed, 3 insertions(+), 30 deletions(-)
+
+diff --git a/content/browser/renderer_host/window_utils_efl.cc b/content/browser/renderer_host/window_utils_efl.cc
+index 2834d59..95caa4e 100644
+--- a/content/browser/renderer_host/window_utils_efl.cc
++++ b/content/browser/renderer_host/window_utils_efl.cc
+@@ -6,44 +6,17 @@
+ #include "ui/gfx/rect.h"
+ #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
++#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
+ #include <Ecore_X.h>
+ namespace content {
+-namespace {
+-
+-// Length of an inch in CSS's 1px unit.
+-const int kPixelsPerInch = 96;
+-
+-int depthPerComponent(int depth) {
+-    switch (depth) {
+-    case 0:
+-    case 24:
+-    case 32:
+-        return 8;
+-    case 8:
+-        return 2;
+-    default:
+-        return depth / 3;
+-    }
+-}
+-
+-}
+-
+ void GetScreenInfoEfl(WebKit::WebScreenInfo* results) {
+   Ecore_X_Display* display = ecore_x_display_get();
+   Ecore_X_Screen* screen = ecore_x_default_screen_get();
+-  int width, height;
+-  ecore_x_screen_size_get(screen, &width, &height);
+-  int depth = ecore_x_default_depth_get(display, screen);
+-  results->deviceScaleFactor = ecore_x_dpi_get() / kPixelsPerInch;
+-  results->isMonochrome = depth == 1;
+-  results->depth = depth;
+-  results->depthPerComponent = depthPerComponent(depth);
+-  // FIXME: not sure how to get available rect.
+-  results->rect = WebKit::WebRect(0, 0, width, height);
+-  results->availableRect = results->rect;
++  *results = WebKit::WebScreenInfoFactory::screenInfo(
++      reinterpret_cast<Display*>(display), ecore_x_screen_index_get(screen));
+ }
+ } // namespace content
+-- 
+1.8.1.2
+
diff --git a/patchset/0033-Workaround-for-X-window-update-delay.patch b/patchset/0033-Workaround-for-X-window-update-delay.patch
new file mode 100644 (file)
index 0000000..9eb1631
--- /dev/null
@@ -0,0 +1,41 @@
+From cbd3bc8c8c818223018aff3564350b3de753f40d Mon Sep 17 00:00:00 2001
+From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Date: Tue, 10 Sep 2013 13:43:53 +0300
+Subject: [PATCH 33/33] Workaround for X window update delay.
+
+---
+ content/browser/renderer_host/render_widget_host_view_efl.cc | 2 ++
+ ui/gfx/preserve_window_efl.cc                                | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
+index 0ee06af..182abd0 100644
+--- a/content/browser/renderer_host/render_widget_host_view_efl.cc
++++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
+@@ -480,6 +480,8 @@ void RenderWidgetHostViewEfl::AcceleratedSurfaceBuffersSwapped(
+     ack_params.sync_point = 0;
+     RenderWidgetHostImpl::AcknowledgeBufferPresent(
+       params.route_id, gpu_host_id, ack_params);
++
++    evas_object_smart_changed(preserve_window_->SmartObject());
+ }
+ void RenderWidgetHostViewEfl::AcceleratedSurfacePostSubBuffer(
+diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
+index 2d783e3..cc9e34f 100644
+--- a/ui/gfx/preserve_window_efl.cc
++++ b/ui/gfx/preserve_window_efl.cc
+@@ -269,6 +269,10 @@ void PreserveWindow::HandleEvasObjectResize(Evas_Object* o,
+ }
+ void PreserveWindow::HandleEvasObjectCalculate(Evas_Object* o) {
++  PreserveWindowData* smart_data = ToSmartData(o);
++  // FIXME : This is nasty hack to force update X window on the device. Should find a better solution!
++  ecore_x_window_hide(smart_data->window);
++  ecore_x_window_show(smart_data->window);
+ }
+ PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
+-- 
+1.8.1.2
+