XWalk WebView patchset, README and LICENSE files.
[platform/framework/web/xwalk_webview.git] / patchset / 0001-Link-content-shell-against-EFL.patch
1 From d34de9b3c07bfaa3155deecf1155a5b6cd2af493 Mon Sep 17 00:00:00 2001
2 From: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
3 Date: Tue, 11 Jun 2013 14:32:49 +0300
4 Subject: [PATCH 01/33] Link content-shell against EFL.
5
6 Define TOOLKIT_EFL.
7 gyp: Define `toolkit_uses_efl'.
8 Add an inital implementation of WebViewContentsEfl.
9 Add efl_util.{cc,h} to initialize and shut down the EFL.
10 Add MessagePumpEfl.
11 Build ShellEfl.
12 ---
13  base/base.gyp                                      |  16 ++
14  base/message_loop.h                                |   2 +
15  base/message_pump_efl.cc                           | 174 ++++++++++++++
16  base/message_pump_efl.h                            |  66 +++++
17  build/build_config.h                               |   1 +
18  build/common.gypi                                  |   4 +
19  build/linux/system.gyp                             |  21 ++
20  content/browser/browser_main_loop.cc               |  11 +
21  content/browser/power_save_blocker_x11.cc          |   4 +-
22  .../browser/web_contents/web_contents_view_efl.cc  | 265 +++++++++++++++++++++
23  .../browser/web_contents/web_contents_view_efl.h   |  97 ++++++++
24  content/content_browser.gypi                       |  11 +
25  content/content_shell.gypi                         |  10 +
26  content/shell/shell.h                              |  16 +-
27  content/shell/shell_efl.cc                         | 110 +++++++++
28  ui/gfx/efl_util.cc                                 |  33 +++
29  ui/gfx/efl_util.h                                  |  20 ++
30  ui/ui.gyp                                          |   9 +
31  18 files changed, 867 insertions(+), 3 deletions(-)
32  create mode 100644 base/message_pump_efl.cc
33  create mode 100644 base/message_pump_efl.h
34  create mode 100644 content/browser/web_contents/web_contents_view_efl.cc
35  create mode 100644 content/browser/web_contents/web_contents_view_efl.h
36  create mode 100644 content/shell/shell_efl.cc
37  create mode 100644 ui/gfx/efl_util.cc
38  create mode 100644 ui/gfx/efl_util.h
39
40 diff --git a/base/base.gyp b/base/base.gyp
41 index 8b3ebac..b9e7e36 100644
42 --- a/base/base.gyp
43 +++ b/base/base.gyp
44 @@ -79,6 +79,22 @@
45                ['exclude', '_nss\\.cc$'],
46              ],
47          }],
48 +        ['toolkit_uses_efl==1', {
49 +          'dependencies': [
50 +            '../build/linux/system.gyp:efl',
51 +          ],
52 +          'export_dependent_settings': [
53 +            '../build/linux/system.gyp:efl',
54 +          ],
55 +          'sources': [
56 +            'message_pump_efl.cc',
57 +            'message_pump_efl.h',
58 +          ],
59 +          'sources/': [
60 +            ['exclude', 'message_pump_gtk.cc'],
61 +            ['exclude', 'message_pump_gtk.h'],
62 +          ],
63 +        }],
64          ['use_x11==1', {
65            'dependencies': [
66              '../build/linux/system.gyp:x11',
67 diff --git a/base/message_loop.h b/base/message_loop.h
68 index f3ad3a5..8a1cc06 100644
69 --- a/base/message_loop.h
70 +++ b/base/message_loop.h
71 @@ -36,6 +36,8 @@
72  #include "base/message_pump_aurax11.h"
73  #elif defined(USE_OZONE) && !defined(OS_NACL)
74  #include "base/message_pump_ozone.h"
75 +#elif defined(TOOLKIT_EFL)
76 +#include "base/message_pump_efl.h"
77  #else
78  #include "base/message_pump_gtk.h"
79  #endif
80 diff --git a/base/message_pump_efl.cc b/base/message_pump_efl.cc
81 new file mode 100644
82 index 0000000..cdfe740
83 --- /dev/null
84 +++ b/base/message_pump_efl.cc
85 @@ -0,0 +1,174 @@
86 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
87 +// Use of this source code is governed by a BSD-style license that can be
88 +// found in the LICENSE file.
89 +
90 +#include "base/message_pump_efl.h"
91 +
92 +#include <Ecore.h>
93 +#include <Ecore_X.h>
94 +#include <X11/Xlib.h>
95 +
96 +#include "base/debug/trace_event.h"
97 +#include "base/logging.h"
98 +#include "base/posix/eintr_wrapper.h"
99 +#include "base/threading/platform_thread.h"
100 +
101 +namespace {
102 +static const int ecorePipeMessageSize = 1;
103 +static const char wakupEcorePipeMessage[] = "W";
104 +
105 +void WakeUpEvent(void* data, void*, unsigned int) {
106 +  static_cast<base::MessagePumpEfl*>(data)->HandleDispatch();
107 +}
108 +
109 +}  // namespace
110 +
111 +namespace base {
112 +
113 +// We may make recursive calls to Run, so we save state that needs to be
114 +// separate between them in this structure type.
115 +struct RunState {
116 +  MessagePump::Delegate* delegate;
117 +  MessagePumpDispatcher* dispatcher;
118 +
119 +  // Used to flag that the current Run() invocation should return ASAP.
120 +  bool should_quit;
121 +
122 +  // Used to count how many Run() invocations are on the stack.
123 +  int run_depth;
124 +};
125 +
126 +struct MessagePumpEfl::Private {
127 +  RunState* state_;
128 +
129 +  // This is the time when we need to do delayed work.
130 +  TimeTicks delayed_work_time_;
131 +
132 +  // List of observers.
133 +  ObserverList<MessagePumpObserver> observers_;
134 +
135 +  Ecore_Pipe* wakeup_pipe_;
136 +};
137 +
138 +MessagePumpEfl::MessagePumpEfl()
139 +    : private_(new Private) {
140 +  private_->state_ = NULL;
141 +  private_->wakeup_pipe_ = ecore_pipe_add(WakeUpEvent, this);
142 +}
143 +
144 +MessagePumpEfl::~MessagePumpEfl() {
145 +  ecore_pipe_del(private_->wakeup_pipe_);
146 +}
147 +
148 +void MessagePumpEfl::RunWithDispatcher(Delegate* delegate,
149 +                                       MessagePumpDispatcher* dispatcher) {
150 +#ifndef NDEBUG
151 +  // Make sure we only run this on one thread. X/GTK only has one message pump
152 +  // so we can only have one UI loop per process.
153 +  static base::PlatformThreadId thread_id = base::PlatformThread::CurrentId();
154 +  DCHECK(thread_id == base::PlatformThread::CurrentId()) <<
155 +      "Running MessagePumpEfl on two different threads; "
156 +      "this is unsupported by Ecore!";
157 +#endif
158 +
159 +  RunState state;
160 +  state.delegate = delegate;
161 +  state.dispatcher = dispatcher;
162 +  state.should_quit = false;
163 +  state.run_depth = private_->state_ ? private_->state_->run_depth + 1 : 1;
164 +
165 +  RunState* previous_state = private_->state_;
166 +  private_->state_ = &state;
167 +
168 +  bool more_work_is_plausible = true;
169 +
170 +  for (;;) {
171 +    ecore_main_loop_iterate();
172 +    more_work_is_plausible = false;
173 +    if (private_->state_->should_quit)
174 +      break;
175 +
176 +    more_work_is_plausible |= private_->state_->delegate->DoWork();
177 +    if (private_->state_->should_quit)
178 +      break;
179 +
180 +    more_work_is_plausible |=
181 +      private_->state_->delegate->DoDelayedWork(&private_->delayed_work_time_);
182 +    if (private_->state_->should_quit)
183 +      break;
184 +
185 +    if (more_work_is_plausible)
186 +      continue;
187 +
188 +    more_work_is_plausible = private_->state_->delegate->DoIdleWork();
189 +    if (private_->state_->should_quit)
190 +      break;
191 +  }
192 +
193 +  private_->state_ = previous_state;
194 +}
195 +
196 +void MessagePumpEfl::HandleDispatch() {
197 +  private_->state_->delegate->DoWork();
198 +  if (private_->state_->should_quit)
199 +    return;
200 +
201 +  private_->state_->delegate->DoDelayedWork(&private_->delayed_work_time_);
202 +}
203 +
204 +void MessagePumpEfl::AddObserver(MessagePumpObserver* observer) {
205 +  private_->observers_.AddObserver(observer);
206 +}
207 +
208 +void MessagePumpEfl::RemoveObserver(MessagePumpObserver* observer) {
209 +  private_->observers_.RemoveObserver(observer);
210 +}
211 +
212 +void MessagePumpEfl::Run(Delegate* delegate) {
213 +  RunWithDispatcher(delegate, NULL);
214 +}
215 +
216 +void MessagePumpEfl::Quit() {
217 +  if (private_->state_) {
218 +    private_->state_->should_quit = true;
219 +  } else {
220 +    NOTREACHED() << "Quit called outside Run!";
221 +  }
222 +}
223 +
224 +void MessagePumpEfl::ScheduleWork() {
225 +  // This can be called on any thread, so we don't want to touch any state
226 +  // variables as we would then need locks all over.  This ensures that if
227 +  // we are sleeping in a poll that we will wake up.
228 +  if (HANDLE_EINTR(ecore_pipe_write(private_->wakeup_pipe_, wakupEcorePipeMessage, ecorePipeMessageSize)) != 1) {
229 +    NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
230 +  }
231 +}
232 +
233 +void MessagePumpEfl::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
234 +  // We need to wake up the loop in case the poll timeout needs to be
235 +  // adjusted.  This will cause us to try to do work, but that's ok.
236 +  private_->delayed_work_time_ = delayed_work_time;
237 +  ScheduleWork();
238 +}
239 +
240 +MessagePumpDispatcher* MessagePumpEfl::GetDispatcher() {
241 +  return private_->state_ ? private_->state_->dispatcher : NULL;
242 +}
243 +
244 +ObserverList<MessagePumpObserver>& MessagePumpEfl::observers() {
245 +  return private_->observers_;
246 +}
247 +
248 +Display* MessagePumpEfl::GetDefaultXDisplay() {
249 +  static Ecore_X_Display* display = ecore_x_display_get();
250 +  if (!display) {
251 +    // Ecore_X has not been initialized, which is a decision we wish to
252 +    // support, for example for the GPU process.
253 +    static Display* xdisplay = XOpenDisplay(NULL);
254 +    return xdisplay;
255 +  }
256 +  return static_cast<Display*>(display);
257 +}
258 +
259 +}  // namespace base
260 diff --git a/base/message_pump_efl.h b/base/message_pump_efl.h
261 new file mode 100644
262 index 0000000..7f63188
263 --- /dev/null
264 +++ b/base/message_pump_efl.h
265 @@ -0,0 +1,66 @@
266 +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
267 +// Use of this source code is governed by a BSD-style license that can be
268 +// found in the LICENSE file.
269 +
270 +#ifndef BASE_MESSAGE_PUMP_EFL_H_
271 +#define BASE_MESSAGE_PUMP_EFL_H_
272 +
273 +#include "base/base_export.h"
274 +#include "base/event_types.h"
275 +#include "base/memory/scoped_ptr.h"
276 +#include "base/message_pump.h"
277 +#include "base/message_pump_dispatcher.h"
278 +#include "base/message_pump_observer.h"
279 +#include "base/observer_list.h"
280 +#include "base/time.h"
281 +
282 +typedef struct _XDisplay Display;
283 +
284 +namespace base {
285 +
286 +class BASE_EXPORT MessagePumpEfl : public MessagePump {
287 +public:
288 +  MessagePumpEfl();
289 +
290 +  // Like MessagePump::Run, but events are routed through dispatcher.
291 +  virtual void RunWithDispatcher(Delegate* delegate,
292 +                                 MessagePumpDispatcher* dispatcher);
293 +
294 +  void HandleDispatch();
295 +
296 +  // Adds an Observer, which will start receiving notifications immediately.
297 +  void AddObserver(MessagePumpObserver* observer);
298 +
299 +  // Removes an Observer.  It is safe to call this method while an Observer is
300 +  // receiving a notification callback.
301 +  void RemoveObserver(MessagePumpObserver* observer);
302 +
303 +  // Overridden from MessagePump:
304 +  virtual void Run(Delegate* delegate) OVERRIDE;
305 +  virtual void Quit() OVERRIDE;
306 +  virtual void ScheduleWork() OVERRIDE;
307 +  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
308 +
309 +  // Returns default X Display.
310 +  static Display* GetDefaultXDisplay();
311 +
312 +protected:
313 +  virtual ~MessagePumpEfl();
314 +
315 +  // Returns the dispatcher for the current run state (|state_->dispatcher|).
316 +  MessagePumpDispatcher* GetDispatcher();
317 +
318 +  ObserverList<MessagePumpObserver>& observers();
319 +
320 +private:
321 +  struct Private;
322 +  scoped_ptr<Private> private_;
323 +
324 +  DISALLOW_COPY_AND_ASSIGN(MessagePumpEfl);
325 +};
326 +
327 +typedef MessagePumpEfl MessagePumpForUI;
328 +
329 +}  // namespace base
330 +
331 +#endif  // BASE_MESSAGE_PUMP_EFL_H_
332 diff --git a/build/build_config.h b/build/build_config.h
333 index fef6be5..dd7443e 100644
334 --- a/build/build_config.h
335 +++ b/build/build_config.h
336 @@ -33,6 +33,7 @@
337  // Use TOOLKIT_GTK on linux if TOOLKIT_VIEWS isn't defined.
338  #if !defined(TOOLKIT_VIEWS) && defined(USE_X11)
339  #define TOOLKIT_GTK
340 +#define TOOLKIT_EFL
341  #endif
342  #elif defined(_WIN32)
343  #define OS_WIN 1
344 diff --git a/build/common.gypi b/build/common.gypi
345 index 6452ffa..9753413 100644
346 --- a/build/common.gypi
347 +++ b/build/common.gypi
348 @@ -138,8 +138,10 @@
349  
350            # Set toolkit_uses_gtk for the Chromium browser on Linux.
351            ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_aura==0 and use_ozone==0', {
352 +            'toolkit_uses_efl%': 1,
353              'toolkit_uses_gtk%': 1,
354            }, {
355 +            'toolkit_uses_efl%': 0,
356              'toolkit_uses_gtk%': 0,
357            }],
358  
359 @@ -188,6 +190,7 @@
360        'host_arch%': '<(host_arch)',
361        'target_arch%': '<(target_arch)',
362        'toolkit_views%': '<(toolkit_views)',
363 +      'toolkit_uses_efl%': '<(toolkit_uses_efl)',
364        'toolkit_uses_gtk%': '<(toolkit_uses_gtk)',
365        'use_aura%': '<(use_aura)',
366        'use_ash%': '<(use_ash)',
367 @@ -751,6 +754,7 @@
368      'os_posix%': '<(os_posix)',
369      'use_glib%': '<(use_glib)',
370      'use_ozone%': '<(use_ozone)',
371 +    'toolkit_uses_efl%': '<(toolkit_uses_efl)',
372      'toolkit_uses_gtk%': '<(toolkit_uses_gtk)',
373      'use_x11%': '<(use_x11)',
374      'use_gnome_keyring%': '<(use_gnome_keyring)',
375 diff --git a/build/linux/system.gyp b/build/linux/system.gyp
376 index b925792..4b13e70 100644
377 --- a/build/linux/system.gyp
378 +++ b/build/linux/system.gyp
379 @@ -246,6 +246,27 @@
380        ],
381      },
382      {
383 +      'target_name': 'efl',
384 +      'type': 'none',
385 +      'toolsets': ['host', 'target'],
386 +      'variables': {
387 +        'efl_libs': 'eina evas ecore ecore-evas ecore-file ecore-imf ecore-input ecore-x edje elementary',
388 +      },
389 +      'direct_dependent_settings': {
390 +        'cflags': [
391 +          '<!@(<(pkg-config) --cflags <(efl_libs))',
392 +        ],
393 +      },
394 +      'link_settings': {
395 +        'ldflags': [
396 +          '<!@(<(pkg-config) --libs-only-L --libs-only-other <(efl_libs))',
397 +        ],
398 +        'libraries': [
399 +          '<!@(<(pkg-config) --libs-only-l <(efl_libs))',
400 +        ],
401 +      },
402 +    },
403 +    {
404        'target_name': 'freetype2',
405        'type': 'none',
406        'conditions': [
407 diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
408 index 31f9f17..37cdf9c 100644
409 --- a/content/browser/browser_main_loop.cc
410 +++ b/content/browser/browser_main_loop.cc
411 @@ -88,6 +88,10 @@
412  #include "ui/gfx/gtk_util.h"
413  #endif
414  
415 +#if defined(TOOLKIT_EFL)
416 +#include "ui/gfx/efl_util.h"
417 +#endif
418 +
419  #if defined(OS_POSIX) && !defined(OS_MACOSX)
420  #include <sys/stat.h>
421  
422 @@ -289,6 +293,9 @@ BrowserMainLoop::~BrowserMainLoop() {
423  #if !defined(OS_IOS)
424    ui::Clipboard::DestroyClipboardForCurrentThread();
425  #endif  // !defined(OS_IOS)
426 +#if defined(TOOLKIT_EFL)
427 +  gfx::EflShutdown();
428 +#endif
429    g_current_browser_main_loop = NULL;
430  }
431  
432 @@ -832,6 +839,10 @@ void BrowserMainLoop::InitializeToolkit() {
433    gfx::GtkInitFromCommandLine(parsed_command_line_);
434  #endif
435  
436 +#if defined(TOOLKIT_EFL)
437 +  gfx::EflInit();
438 +#endif
439 +
440    SetUpGLibLogHandler();
441  #endif
442  
443 diff --git a/content/browser/power_save_blocker_x11.cc b/content/browser/power_save_blocker_x11.cc
444 index c7dba77..9a8aff1 100644
445 --- a/content/browser/power_save_blocker_x11.cc
446 +++ b/content/browser/power_save_blocker_x11.cc
447 @@ -22,7 +22,9 @@
448  #include "base/memory/scoped_ptr.h"
449  #include "base/memory/singleton.h"
450  #include "base/message_loop_proxy.h"
451 -#if defined(TOOLKIT_GTK)
452 +#if defined(TOOLKIT_EFL)
453 +#include "base/message_pump_efl.h"
454 +#elif defined(TOOLKIT_GTK)
455  #include "base/message_pump_gtk.h"
456  #else
457  #include "base/message_pump_aurax11.h"
458 diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
459 new file mode 100644
460 index 0000000..a3a4196
461 --- /dev/null
462 +++ b/content/browser/web_contents/web_contents_view_efl.cc
463 @@ -0,0 +1,265 @@
464 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
465 +// Use of this source code is governed by a BSD-style license that can be
466 +// found in the LICENSE file.
467 +
468 +#include "content/browser/web_contents/web_contents_view_efl.h"
469 +
470 +#include <gdk/gdk.h>
471 +#include <gdk/gdkkeysyms.h>
472 +#include <gtk/gtk.h>
473 +
474 +#include <algorithm>
475 +
476 +#include "base/string_util.h"
477 +#include "base/utf_string_conversions.h"
478 +#include "build/build_config.h"
479 +#include "content/browser/renderer_host/render_view_host_factory.h"
480 +#include "content/browser/renderer_host/render_view_host_impl.h"
481 +#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
482 +#include "content/browser/web_contents/interstitial_page_impl.h"
483 +#include "content/browser/web_contents/web_contents_impl.h"
484 +#include "content/browser/web_contents/web_drag_dest_gtk.h"
485 +#include "content/browser/web_contents/web_drag_source_gtk.h"
486 +#include "content/public/browser/web_contents_delegate.h"
487 +#include "content/public/browser/web_contents_view_delegate.h"
488 +#include "ui/base/gtk/gtk_expanded_container.h"
489 +#include "ui/gfx/image/image_skia.h"
490 +#include "ui/gfx/point.h"
491 +#include "ui/gfx/rect.h"
492 +#include "ui/gfx/size.h"
493 +#include "webkit/glue/webdropdata.h"
494 +
495 +using WebKit::WebDragOperation;
496 +using WebKit::WebDragOperationsMask;
497 +
498 +namespace content {
499 +namespace {
500 +
501 +// Called when the mouse leaves the widget. We notify our delegate.
502 +gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
503 +                       WebContentsImpl* web_contents) {
504 +  if (web_contents->GetDelegate())
505 +    web_contents->GetDelegate()->ContentsMouseEvent(
506 +        web_contents, gfx::Point(event->x_root, event->y_root), false);
507 +  return FALSE;
508 +}
509 +
510 +// Called when the mouse moves within the widget. We notify our delegate.
511 +gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
512 +                     WebContentsImpl* web_contents) {
513 +  if (web_contents->GetDelegate())
514 +    web_contents->GetDelegate()->ContentsMouseEvent(
515 +        web_contents, gfx::Point(event->x_root, event->y_root), true);
516 +  return FALSE;
517 +}
518 +
519 +// See tab_contents_view_views.cc for discussion of mouse scroll zooming.
520 +gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
521 +                       WebContentsImpl* web_contents) {
522 +  if ((event->state & gtk_accelerator_get_default_mod_mask()) !=
523 +      GDK_CONTROL_MASK) {
524 +    return FALSE;
525 +  }
526 +
527 +  WebContentsDelegate* delegate = web_contents->GetDelegate();
528 +  if (!delegate)
529 +    return FALSE;
530 +
531 +  if (!(event->direction == GDK_SCROLL_DOWN ||
532 +        event->direction == GDK_SCROLL_UP)) {
533 +    return FALSE;
534 +  }
535 +
536 +  delegate->ContentsZoomChange(event->direction == GDK_SCROLL_UP);
537 +  return TRUE;
538 +}
539 +
540 +}  // namespace
541 +
542 +WebContentsViewPort* CreateWebContentsView(
543 +    WebContentsImpl* web_contents,
544 +    WebContentsViewDelegate* delegate,
545 +    RenderViewHostDelegateView** render_view_host_delegate_view) {
546 +  WebContentsViewEfl* rv = new WebContentsViewEfl(web_contents, delegate);
547 +  *render_view_host_delegate_view = rv;
548 +  return rv;
549 +}
550 +
551 +WebContentsViewEfl::WebContentsViewEfl(
552 +    WebContentsImpl* web_contents,
553 +    WebContentsViewDelegate* delegate)
554 +    : web_contents_(web_contents),
555 +      delegate_(delegate) {
556 +}
557 +
558 +WebContentsViewEfl::~WebContentsViewEfl() {
559 +}
560 +
561 +gfx::NativeView WebContentsViewEfl::GetNativeView() const {
562 +  if (delegate_)
563 +    return delegate_->GetNativeView();
564 +
565 +  return 0;
566 +}
567 +
568 +gfx::NativeView WebContentsViewEfl::GetContentNativeView() const {
569 +  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
570 +  if (!rwhv)
571 +    return NULL;
572 +  return rwhv->GetNativeView();
573 +}
574 +
575 +gfx::NativeWindow WebContentsViewEfl::GetTopLevelNativeWindow() const {
576 +  return 0;
577 +}
578 +
579 +void WebContentsViewEfl::GetContainerBounds(gfx::Rect* out) const {
580 +}
581 +
582 +void WebContentsViewEfl::OnTabCrashed(base::TerminationStatus status,
583 +                                      int error_code) {
584 +}
585 +
586 +void WebContentsViewEfl::Focus() {
587 +  if (web_contents_->ShowingInterstitialPage()) {
588 +    web_contents_->GetInterstitialPage()->Focus();
589 +  } else if (delegate_) {
590 +    delegate_->Focus();
591 +  }
592 +}
593 +
594 +void WebContentsViewEfl::SetInitialFocus() {
595 +  if (web_contents_->FocusLocationBarByDefault())
596 +    web_contents_->SetFocusToLocationBar(false);
597 +  else
598 +    Focus();
599 +}
600 +
601 +void WebContentsViewEfl::StoreFocus() {
602 +}
603 +
604 +void WebContentsViewEfl::RestoreFocus() {
605 +    SetInitialFocus();
606 +}
607 +
608 +WebDropData* WebContentsViewEfl::GetDropData() const {
609 +  return 0;
610 +}
611 +
612 +gfx::Rect WebContentsViewEfl::GetViewBounds() const {
613 +  gfx::Rect rect;
614 +  GdkWindow* window = gtk_widget_get_window(GetNativeView());
615 +  if (!window) {
616 +    rect.SetRect(0, 0, requested_size_.width(), requested_size_.height());
617 +    return rect;
618 +  }
619 +  int x = 0, y = 0, w, h;
620 +  gdk_window_get_geometry(window, &x, &y, &w, &h, NULL);
621 +  rect.SetRect(x, y, w, h);
622 +  return rect;
623 +}
624 +
625 +void WebContentsViewEfl::CreateView(
626 +    const gfx::Size& initial_size, gfx::NativeView context) {
627 +  requested_size_ = initial_size;
628 +}
629 +
630 +RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
631 +    RenderWidgetHost* render_widget_host) {
632 +  if (render_widget_host->GetView()) {
633 +    DCHECK(RenderViewHostFactory::has_factory());
634 +    return render_widget_host->GetView();
635 +  }
636 +
637 +  RenderWidgetHostView* view =
638 +      RenderWidgetHostView::CreateViewForWidget(render_widget_host);
639 +  view->InitAsChild(NULL);
640 +  if (render_widget_host->IsRenderView()) {
641 +    RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
642 +    if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
643 +      UpdateDragDest(rvh);
644 +  }
645 +
646 +  return view;
647 +}
648 +
649 +RenderWidgetHostView* WebContentsViewEfl::CreateViewForPopupWidget(
650 +    RenderWidgetHost* render_widget_host) {
651 +  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
652 +}
653 +
654 +void WebContentsViewEfl::SetPageTitle(const string16& title) {
655 +}
656 +
657 +void WebContentsViewEfl::SizeContents(const gfx::Size& size) {
658 +  requested_size_ = size;
659 +  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
660 +  if (rwhv)
661 +    rwhv->SetSize(size);
662 +}
663 +
664 +void WebContentsViewEfl::RenderViewCreated(RenderViewHost* host) {
665 +}
666 +
667 +void WebContentsViewEfl::RenderViewSwappedIn(RenderViewHost* host) {
668 +  UpdateDragDest(host);
669 +}
670 +
671 +void WebContentsViewEfl::SetOverscrollControllerEnabled(bool enabled) {
672 +}
673 +
674 +WebContents* WebContentsViewEfl::web_contents() {
675 +  return web_contents_;
676 +}
677 +
678 +void WebContentsViewEfl::UpdateDragCursor(WebDragOperation operation) {
679 +}
680 +
681 +void WebContentsViewEfl::GotFocus() {
682 +}
683 +
684 +// This is called when the renderer asks us to take focus back (i.e., it has
685 +// iterated past the last focusable element on the page).
686 +void WebContentsViewEfl::TakeFocus(bool reverse) {
687 +  if (!web_contents_->GetDelegate())
688 +    return;
689 +  if (!web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
690 +      GetTopLevelNativeWindow()) {
691 +    gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()),
692 +        reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
693 +  }
694 +}
695 +
696 +void WebContentsViewEfl::UpdateDragDest(RenderViewHost* host) {
697 +}
698 +
699 +void WebContentsViewEfl::ShowContextMenu(
700 +    const ContextMenuParams& params,
701 +    ContextMenuSourceType type) {
702 +  if (delegate_)
703 +    delegate_->ShowContextMenu(params, type);
704 +  else
705 +    DLOG(ERROR) << "Cannot show context menus without a delegate.";
706 +}
707 +
708 +void WebContentsViewEfl::ShowPopupMenu(const gfx::Rect& bounds,
709 +                                       int item_height,
710 +                                       double item_font_size,
711 +                                       int selected_item,
712 +                                       const std::vector<WebMenuItem>& items,
713 +                                       bool right_aligned,
714 +                                       bool allow_multiple_selection) {
715 +  // External popup menus are only used on Mac and Android.
716 +  NOTIMPLEMENTED();
717 +}
718 +
719 +// Render view DnD -------------------------------------------------------------
720 +
721 +void WebContentsViewEfl::StartDragging(const WebDropData& drop_data,
722 +                                       WebDragOperationsMask ops,
723 +                                       const gfx::ImageSkia& image,
724 +                                       const gfx::Vector2d& image_offset,
725 +                                       const DragEventSourceInfo& event_info) {
726 +}
727 +
728 +}  // namespace content
729 diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
730 new file mode 100644
731 index 0000000..495d4ff
732 --- /dev/null
733 +++ b/content/browser/web_contents/web_contents_view_efl.h
734 @@ -0,0 +1,97 @@
735 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
736 +// Use of this source code is governed by a BSD-style license that can be
737 +// found in the LICENSE file.
738 +
739 +#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
740 +#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
741 +
742 +#include <vector>
743 +
744 +#include "base/memory/scoped_ptr.h"
745 +#include "content/common/content_export.h"
746 +#include "content/common/drag_event_source_info.h"
747 +#include "content/port/browser/render_view_host_delegate_view.h"
748 +#include "content/port/browser/web_contents_view_port.h"
749 +
750 +#include <Evas.h>
751 +
752 +namespace content {
753 +
754 +class WebContents;
755 +class WebContentsImpl;
756 +class WebContentsViewDelegate;
757 +
758 +class CONTENT_EXPORT WebContentsViewEfl
759 +    : public WebContentsViewPort,
760 +      public RenderViewHostDelegateView {
761 + public:
762 +  WebContentsViewEfl(WebContentsImpl* web_contents,
763 +                     WebContentsViewDelegate* delegate);
764 +  virtual ~WebContentsViewEfl();
765 +
766 +  WebContentsViewDelegate* delegate() const { return delegate_.get(); }
767 +  WebContents* web_contents();
768 +
769 +  // WebContentsView implementation --------------------------------------------
770 +
771 +  virtual gfx::NativeView GetNativeView() const OVERRIDE;
772 +  virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
773 +  virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
774 +  virtual void GetContainerBounds(gfx::Rect* out) const OVERRIDE;
775 +  virtual void OnTabCrashed(base::TerminationStatus status,
776 +                            int error_code) OVERRIDE;
777 +  virtual void SizeContents(const gfx::Size& size) OVERRIDE;
778 +  virtual void Focus() OVERRIDE;
779 +  virtual void SetInitialFocus() OVERRIDE;
780 +  virtual void StoreFocus() OVERRIDE;
781 +  virtual void RestoreFocus() OVERRIDE;
782 +  virtual WebDropData* GetDropData() const OVERRIDE;
783 +  virtual gfx::Rect GetViewBounds() const OVERRIDE;
784 +
785 +  // WebContentsViewPort implementation ----------------------------------------
786 +  virtual void CreateView(
787 +      const gfx::Size& initial_size, gfx::NativeView context) OVERRIDE;
788 +  virtual RenderWidgetHostView* CreateViewForWidget(
789 +      RenderWidgetHost* render_widget_host) OVERRIDE;
790 +  virtual RenderWidgetHostView* CreateViewForPopupWidget(
791 +      RenderWidgetHost* render_widget_host) OVERRIDE;
792 +  virtual void SetPageTitle(const string16& title) OVERRIDE;
793 +  virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
794 +  virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
795 +  virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
796 +
797 +  // Backend implementation of RenderViewHostDelegateView.
798 +  virtual void ShowContextMenu(
799 +      const ContextMenuParams& params,
800 +      ContextMenuSourceType type) OVERRIDE;
801 +  virtual void ShowPopupMenu(const gfx::Rect& bounds,
802 +                             int item_height,
803 +                             double item_font_size,
804 +                             int selected_item,
805 +                             const std::vector<WebMenuItem>& items,
806 +                             bool right_aligned,
807 +                             bool allow_multiple_selection) OVERRIDE;
808 +  virtual void StartDragging(const WebDropData& drop_data,
809 +                             WebKit::WebDragOperationsMask allowed_ops,
810 +                             const gfx::ImageSkia& image,
811 +                             const gfx::Vector2d& image_offset,
812 +                             const DragEventSourceInfo& event_info) OVERRIDE;
813 +  virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE;
814 +  virtual void GotFocus() OVERRIDE;
815 +  virtual void TakeFocus(bool reverse) OVERRIDE;
816 +
817 + private:
818 +  void UpdateDragDest(RenderViewHost* new_host);
819 +
820 +  WebContentsImpl* web_contents_;
821 +
822 +  scoped_ptr<WebContentsViewDelegate> delegate_;
823 +
824 +  gfx::Size requested_size_;
825 +
826 +  DISALLOW_COPY_AND_ASSIGN(WebContentsViewEfl);
827 +};
828 +
829 +}  // namespace content
830 +
831 +#endif  // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_EFL_H_
832 diff --git a/content/content_browser.gypi b/content/content_browser.gypi
833 index 8fcfbc3..d087938 100644
834 --- a/content/content_browser.gypi
835 +++ b/content/content_browser.gypi
836 @@ -983,6 +983,8 @@
837      'browser/web_contents/web_contents_view_aura.h',
838      'browser/web_contents/web_contents_view_gtk.cc',
839      'browser/web_contents/web_contents_view_gtk.h',
840 +    'browser/web_contents/web_contents_view_efl.cc',
841 +    'browser/web_contents/web_contents_view_efl.h',
842      'browser/web_contents/web_contents_view_guest.cc',
843      'browser/web_contents/web_contents_view_guest.h',
844      'browser/web_contents/web_contents_view_mac.h',
845 @@ -1163,6 +1165,15 @@
846          '../dbus/dbus.gyp:dbus',
847        ],
848      }],
849 +    ['toolkit_uses_efl == 1', {
850 +      'dependencies': [
851 +        '../build/linux/system.gyp:efl',
852 +      ],
853 +      'sources/': [
854 +        ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
855 +        ['exclude', 'browser/web_contents/web_contents_view_gtk.h'],
856 +      ]
857 +    }],
858      ['OS=="linux"', {
859        'dependencies': [
860          '../build/linux/system.gyp:udev',
861 diff --git a/content/content_shell.gypi b/content/content_shell.gypi
862 index 1bf233b..fc8b680 100644
863 --- a/content/content_shell.gypi
864 +++ b/content/content_shell.gypi
865 @@ -40,6 +40,7 @@
866          'test_support_content',
867          'content_resources.gyp:content_resources',
868          '../base/base.gyp:base',
869 +        '<(DEPTH)/build/linux/system.gyp:efl',
870          '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
871          '../build/temp_gyp/googleurl.gyp:googleurl',
872          '../ipc/ipc.gyp:ipc',
873 @@ -82,6 +83,7 @@
874          'shell/shell.h',
875          'shell/shell_android.cc',
876          'shell/shell_aura.cc',
877 +        'shell/shell_efl.cc',
878          'shell/shell_gtk.cc',
879          'shell/shell_mac.mm',
880          'shell/shell_win.cc',
881 @@ -214,6 +216,14 @@
882              ['exclude', 'shell/shell_win.cc'],
883            ],
884          }],  # use_aura==1
885 +        ['toolkit_uses_efl == 1', {
886 +          'dependencies': [
887 +            '../build/linux/system.gyp:efl',
888 +          ],
889 +          'sources/': [
890 +            ['exclude', 'shell/shell_gtk.cc'],
891 +          ],
892 +        }],
893          ['chromeos==1', {
894            'dependencies': [
895              '../ash/ash.gyp:ash',
896 diff --git a/content/shell/shell.h b/content/shell/shell.h
897 index 736bd3f..0d772eb 100644
898 --- a/content/shell/shell.h
899 +++ b/content/shell/shell.h
900 @@ -18,7 +18,9 @@
901  #include "ui/gfx/native_widget_types.h"
902  #include "ui/gfx/size.h"
903  
904 -#if defined(TOOLKIT_GTK)
905 +#if defined(TOOLKIT_EFL)
906 +#include <Evas.h>
907 +#elif defined(TOOLKIT_GTK)
908  #include <gtk/gtk.h>
909  #include "ui/base/gtk/gtk_signal.h"
910  
911 @@ -62,7 +64,7 @@ class Shell : public WebContentsDelegate,
912    void Close();
913    void ShowDevTools();
914    void CloseDevTools();
915 -#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK)
916 +#if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK) || defined(TOOLKIT_EFL)
917    // Resizes the main window to the given dimensions.
918    void SizeTo(int width, int height);
919  #endif
920 @@ -194,6 +196,9 @@ class Shell : public WebContentsDelegate,
921    static ATOM RegisterWindowClass();
922    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
923    static LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);
924 +#elif defined(TOOLKIT_EFL)
925 +  static void OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
926 +                              void* event_info);
927  #elif defined(TOOLKIT_GTK)
928    CHROMEGTK_CALLBACK_0(Shell, void, OnBackButtonClicked);
929    CHROMEGTK_CALLBACK_0(Shell, void, OnForwardButtonClicked);
930 @@ -227,6 +232,13 @@ class Shell : public WebContentsDelegate,
931  #if defined(OS_WIN) && !defined(USE_AURA)
932    WNDPROC default_edit_wnd_proc_;
933    static HINSTANCE instance_handle_;
934 +#elif defined(TOOLKIT_EFL)
935 +  // TODO(rakuco): Once gfx::NativeWindow is set to Evas_Object*, we
936 +  // can just use window_.
937 +  Evas_Object* main_window_;
938 +
939 +  int content_width_;
940 +  int content_height_;
941  #elif defined(TOOLKIT_GTK)
942    GtkWidget* vbox_;
943  
944 diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
945 new file mode 100644
946 index 0000000..19822da
947 --- /dev/null
948 +++ b/content/shell/shell_efl.cc
949 @@ -0,0 +1,110 @@
950 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
951 +// Use of this source code is governed by a BSD-style license that can be
952 +// found in the LICENSE file.
953 +
954 +#include "content/shell/shell.h"
955 +
956 +#include <Ecore.h>
957 +#include <Ecore_Evas.h>
958 +#include <Eina.h>
959 +#include <Elementary.h>
960 +
961 +#include "base/logging.h"
962 +#include "base/strings/string_piece.h"
963 +#include "base/utf_string_conversions.h"
964 +#include "content/public/browser/browser_context.h"
965 +#include "content/public/browser/native_web_keyboard_event.h"
966 +#include "content/public/browser/web_contents.h"
967 +#include "content/public/browser/web_contents_view.h"
968 +#include "content/public/common/renderer_preferences.h"
969 +#include "content/shell/shell_browser_context.h"
970 +#include "content/shell/shell_content_browser_client.h"
971 +
972 +namespace content {
973 +
974 +void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
975 +  elm_init(0, NULL);
976 +  elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
977 +}
978 +
979 +void Shell::PlatformCleanUp() {
980 +}
981 +
982 +void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
983 +  if (headless_)
984 +    return;
985 +}
986 +
987 +void Shell::PlatformSetAddressBarURL(const GURL& url) {
988 +  if (headless_)
989 +    return;
990 +}
991 +
992 +void Shell::PlatformSetIsLoading(bool loading) {
993 +  if (headless_)
994 +    return;
995 +}
996 +
997 +void Shell::PlatformCreateWindow(int width, int height) {
998 +  SizeTo(width, height);
999 +
1000 +  if (headless_)
1001 +    return;
1002 +
1003 +  main_window_ = elm_win_add(NULL, "Content Shell", ELM_WIN_BASIC);
1004 +
1005 +  elm_win_title_set(main_window_, "Content Shell");
1006 +  elm_win_autodel_set(main_window_, true);
1007 +
1008 +  evas_object_resize(main_window_, width, height);
1009 +  evas_object_event_callback_add(main_window_, EVAS_CALLBACK_DEL,
1010 +                                 OnMainWindowDel, this);
1011 +
1012 +  Evas_Object* rect = evas_object_rectangle_add(
1013 +      evas_object_evas_get(main_window_));
1014 +  evas_object_color_set(rect, 255, 0, 0, 255);
1015 +  evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1016 +  elm_win_resize_object_add(main_window_, rect);
1017 +  evas_object_show(rect);
1018 +
1019 +  evas_object_show(main_window_);
1020 +}
1021 +
1022 +void Shell::PlatformSetContents() {
1023 +  if (headless_)
1024 +    return;
1025 +
1026 +  WebContentsView* content_view = web_contents_->GetView();
1027 +}
1028 +
1029 +void Shell::SizeTo(int width, int height) {
1030 +  content_width_ = width;
1031 +  content_height_ = height;
1032 +}
1033 +
1034 +void Shell::PlatformResizeSubViews() {
1035 +  SizeTo(content_width_, content_height_);
1036 +}
1037 +
1038 +void Shell::Close() {
1039 +  if (headless_) {
1040 +    delete this;
1041 +    return;
1042 +  }
1043 +}
1044 +
1045 +void Shell::PlatformSetTitle(const string16& title) {
1046 +  if (headless_)
1047 +    return;
1048 +
1049 +  std::string title_utf8 = UTF16ToUTF8(title);
1050 +  elm_win_title_set(main_window_, title_utf8.c_str());
1051 +}
1052 +
1053 +void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
1054 +                            void* event_info) {
1055 +  Shell* shell = static_cast<Shell*>(data);
1056 +  delete shell;
1057 +}
1058 +
1059 +}  // namespace content
1060 diff --git a/ui/gfx/efl_util.cc b/ui/gfx/efl_util.cc
1061 new file mode 100644
1062 index 0000000..7cd7cb4
1063 --- /dev/null
1064 +++ b/ui/gfx/efl_util.cc
1065 @@ -0,0 +1,33 @@
1066 +// Copyright (c) 2013 Intel Coporation. All rights reserved.
1067 +// Use of this source code is governed by a BSD-style license that can be
1068 +// found in the LICENSE file.
1069 +
1070 +#include "ui/gfx/efl_util.h"
1071 +
1072 +#include <Ecore.h>
1073 +#include <Ecore_Evas.h>
1074 +#include <Ecore_X.h>
1075 +#include <Edje.h>
1076 +#include <Eina.h>
1077 +#include <Evas.h>
1078 +
1079 +namespace gfx {
1080 +
1081 +void EflInit() {
1082 +  eina_init();
1083 +  evas_init();
1084 +  ecore_init();
1085 +  ecore_evas_init();
1086 +  edje_init();
1087 +  ecore_main_loop_glib_integrate();
1088 +}
1089 +
1090 +void EflShutdown() {
1091 +  edje_shutdown();
1092 +  ecore_evas_shutdown();
1093 +  ecore_shutdown();
1094 +  evas_shutdown();
1095 +  eina_shutdown();
1096 +}
1097 +
1098 +}  // namespace gfx
1099 diff --git a/ui/gfx/efl_util.h b/ui/gfx/efl_util.h
1100 new file mode 100644
1101 index 0000000..8f11bed
1102 --- /dev/null
1103 +++ b/ui/gfx/efl_util.h
1104 @@ -0,0 +1,20 @@
1105 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1106 +// Use of this source code is governed by a BSD-style license that can be
1107 +// found in the LICENSE file.
1108 +
1109 +#ifndef UI_GFX_EFL_UTIL_H_
1110 +#define UI_GFX_EFL_UTIL_H_
1111 +
1112 +#include <vector>
1113 +
1114 +#include "base/time.h"
1115 +#include "ui/base/ui_export.h"
1116 +
1117 +namespace gfx {
1118 +
1119 +UI_EXPORT void EflInit();
1120 +UI_EXPORT void EflShutdown();
1121 +
1122 +}  // namespace gfx
1123 +
1124 +#endif  // UI_GFX_EFL_UTIL_H_
1125 diff --git a/ui/ui.gyp b/ui/ui.gyp
1126 index 9169e08..797fd78 100644
1127 --- a/ui/ui.gyp
1128 +++ b/ui/ui.gyp
1129 @@ -693,6 +693,15 @@
1130              'gfx/image/cairo_cached_surface.h',
1131            ],
1132          }],
1133 +        ['toolkit_uses_efl == 1', {
1134 +          'dependencies': [
1135 +            '../build/linux/system.gyp:efl',
1136 +          ],
1137 +          'sources': [
1138 +            'gfx/efl_util.cc',
1139 +            'gfx/efl_util.h',
1140 +          ],
1141 +        }],
1142          ['chromeos==1 or (use_aura==1 and OS=="linux" and use_x11==0)', {
1143            'sources!': [
1144              'base/clipboard/clipboard_aurax11.cc',
1145 -- 
1146 1.8.1.2
1147