XWalk WebView patchset, README and LICENSE files.
[platform/framework/web/xwalk_webview.git] / patchset / 0002-Adding-RenderWidgetHostViewEfl.patch
1 From fe1a73dd1f8f1fb57132e431db2c4fc3e603e6c6 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <dominik.rottsches@intel.com>
3 Date: Fri, 14 Jun 2013 17:47:58 +0300
4 Subject: [PATCH 02/33] Adding RenderWidgetHostViewEfl
5
6 Pass parent container to WebContentsViewEfl
7 Added Screen_efl.cc
8 Introduce view container
9 ---
10  content/browser/gpu/compositor_util.cc             |   2 +-
11  .../renderer_host/render_widget_host_view_efl.cc   | 777 +++++++++++++++++++++
12  .../renderer_host/render_widget_host_view_efl.h    | 317 +++++++++
13  content/browser/renderer_host/window_utils_efl.cc  |  51 ++
14  content/browser/renderer_host/window_utils_efl.h   |  20 +
15  .../browser/web_contents/web_contents_view_efl.cc  |  10 +-
16  .../browser/web_contents/web_contents_view_efl.h   |   6 +
17  content/content_browser.gypi                       |   8 +
18  content/content_shell.gypi                         |   2 +
19  content/shell/shell_efl.cc                         |  20 +-
20  content/shell/shell_web_contents_view_delegate.h   |   2 +-
21  .../shell/shell_web_contents_view_delegate_efl.cc  |  71 ++
22  ui/gfx/efl_util.cc                                 |   2 +
23  ui/gfx/preserve_window_delegate_efl.h              |  47 ++
24  ui/gfx/preserve_window_efl.cc                      | 421 +++++++++++
25  ui/gfx/preserve_window_efl.h                       |  37 +
26  ui/gfx/screen_efl.cc                               |  87 +++
27  ui/ui.gyp                                          |   9 +
28  18 files changed, 1869 insertions(+), 20 deletions(-)
29  create mode 100644 content/browser/renderer_host/render_widget_host_view_efl.cc
30  create mode 100644 content/browser/renderer_host/render_widget_host_view_efl.h
31  create mode 100644 content/browser/renderer_host/window_utils_efl.cc
32  create mode 100644 content/browser/renderer_host/window_utils_efl.h
33  create mode 100644 content/shell/shell_web_contents_view_delegate_efl.cc
34  create mode 100644 ui/gfx/preserve_window_delegate_efl.h
35  create mode 100644 ui/gfx/preserve_window_efl.cc
36  create mode 100644 ui/gfx/preserve_window_efl.h
37  create mode 100644 ui/gfx/screen_efl.cc
38
39 diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
40 index 0b34932..2cdcd7a 100644
41 --- a/content/browser/gpu/compositor_util.cc
42 +++ b/content/browser/gpu/compositor_util.cc
43 @@ -77,7 +77,7 @@ bool IsThreadedCompositingEnabled() {
44  }
45  
46  bool IsForceCompositingModeEnabled() {
47 -#if defined(OS_WIN) && defined(USE_AURA)
48 +#if defined(OS_WIN) && defined(USE_AURA) || defined(TOOLKIT_EFL)
49    // We always want compositing on Aura Windows.
50    return true;
51  #endif
52 diff --git a/content/browser/renderer_host/render_widget_host_view_efl.cc b/content/browser/renderer_host/render_widget_host_view_efl.cc
53 new file mode 100644
54 index 0000000..86fe664
55 --- /dev/null
56 +++ b/content/browser/renderer_host/render_widget_host_view_efl.cc
57 @@ -0,0 +1,777 @@
58 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
59 +// Use of this source code is governed by a BSD-style license that can be
60 +// found in the LICENSE file.
61 +
62 +#include "content/browser/renderer_host/render_widget_host_view_efl.h"
63 +
64 +#include <Elementary.h>
65 +
66 +// If this gets included after the gtk headers, then a bunch of compiler
67 +// errors happen because of a "#define Status int" in Xlib.h, which interacts
68 +// badly with net::URLRequestStatus::Status.
69 +#include "content/common/view_messages.h"
70 +
71 +#include <cairo/cairo.h>
72 +
73 +#include <algorithm>
74 +#include <string>
75 +
76 +#include "base/bind_helpers.h"
77 +#include "base/command_line.h"
78 +#include "base/debug/trace_event.h"
79 +#include "base/logging.h"
80 +#include "base/message_loop.h"
81 +#include "base/metrics/histogram.h"
82 +#include "base/string_number_conversions.h"
83 +#include "base/strings/utf_offset_string_conversions.h"
84 +#include "base/time.h"
85 +#include "base/utf_string_conversions.h"
86 +#include "content/browser/accessibility/browser_accessibility_gtk.h"
87 +#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
88 +#include "content/browser/renderer_host/backing_store_gtk.h"
89 +#include "content/browser/renderer_host/render_view_host_delegate.h"
90 +#include "content/browser/renderer_host/render_view_host_impl.h"
91 +#include "content/browser/renderer_host/window_utils_efl.h"
92 +#include "content/common/edit_command.h"
93 +#include "content/common/gpu/gpu_messages.h"
94 +#include "content/public/browser/browser_context.h"
95 +#include "content/public/browser/native_web_keyboard_event.h"
96 +#include "content/public/common/content_switches.h"
97 +#include "skia/ext/platform_canvas.h"
98 +#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
99 +#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
100 +#include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
101 +#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
102 +#include "ui/base/clipboard/scoped_clipboard_writer.h"
103 +#include "ui/base/gtk/gtk_compat.h"
104 +#include "ui/base/text/text_elider.h"
105 +#include "ui/base/x/active_window_watcher_x.h"
106 +#include "ui/base/x/x11_util.h"
107 +#include "ui/gfx/preserve_window_efl.h"
108 +#include "webkit/glue/webcursor_gtk_data.h"
109 +#include "webkit/plugins/npapi/webplugin.h"
110 +
111 +using WebKit::WebInputEventFactory;
112 +using WebKit::WebMouseWheelEvent;
113 +using WebKit::WebScreenInfo;
114 +
115 +namespace content {
116 +namespace {
117 +
118 +// Paint rects on Linux are bounded by the maximum size of a shared memory
119 +// region. By default that's 32MB, but many distros increase it significantly
120 +// (i.e. to 256MB).
121 +//
122 +// We fetch the maximum value from /proc/sys/kernel/shmmax at runtime and, if
123 +// we exceed that, then we limit the height of the paint rect in the renderer.
124 +//
125 +// These constants are here to ensure that, in the event that we exceed it, we
126 +// end up with something a little more square. Previously we had 4000x4000, but
127 +// people's monitor setups are actually exceeding that these days.
128 +const int kMaxWindowWidth = 10000;
129 +const int kMaxWindowHeight = 10000;
130 +
131 +// See WebInputEventFactor.cpp for a reason for this being the default
132 +// scroll size for linux.
133 +const float kDefaultScrollPixelsPerTick = 160.0f / 3.0f;
134 +
135 +const GdkColor kBGColor =
136 +#if defined(NDEBUG)
137 +  { 0, 0xff * 257, 0xff * 257, 0xff * 257 };
138 +#else
139 +  { 0, 0x00 * 257, 0xff * 257, 0x00 * 257 };
140 +#endif
141 +
142 +// Returns the spinning cursor used for loading state.
143 +GdkCursor* GetMozSpinningCursor() {
144 +  static GdkCursor* moz_spinning_cursor = NULL;
145 +  if (!moz_spinning_cursor) {
146 +    const GdkColor fg = { 0, 0, 0, 0 };
147 +    const GdkColor bg = { 65535, 65535, 65535, 65535 };
148 +    GdkPixmap* source = gdk_bitmap_create_from_data(
149 +        NULL, reinterpret_cast<const gchar*>(moz_spinning_bits), 32, 32);
150 +    GdkPixmap* mask = gdk_bitmap_create_from_data(
151 +        NULL, reinterpret_cast<const gchar*>(moz_spinning_mask_bits), 32, 32);
152 +    moz_spinning_cursor =
153 +        gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
154 +    g_object_unref(source);
155 +    g_object_unref(mask);
156 +  }
157 +  return moz_spinning_cursor;
158 +}
159 +
160 +bool MovedToPoint(const WebKit::WebMouseEvent& mouse_event,
161 +                   const gfx::Point& center) {
162 +  return mouse_event.globalX == center.x() &&
163 +         mouse_event.globalY == center.y();
164 +}
165 +
166 +}  // namespace
167 +
168 +RenderWidgetHostViewEfl::RenderWidgetHostViewEfl(RenderWidgetHost* widget_host)
169 +    : host_(RenderWidgetHostImpl::From(widget_host)),
170 +      about_to_validate_and_paint_(false),
171 +      is_hidden_(false),
172 +      is_loading_(false),
173 +      parent_(NULL),
174 +      is_popup_first_mouse_release_(true),
175 +      was_imcontext_focused_before_grab_(false),
176 +      do_x_grab_(false),
177 +      is_fullscreen_(false),
178 +      made_active_(false),
179 +      mouse_is_being_warped_to_unlocked_position_(false),
180 +      destroy_handler_id_(0),
181 +      dragged_at_horizontal_edge_(0),
182 +      dragged_at_vertical_edge_(0),
183 +      compositing_surface_(gfx::kNullPluginWindow),
184 +      preserve_window_(0) {
185 +  host_->SetView(this);
186 +}
187 +
188 +RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
189 +  UnlockMouse();
190 +}
191 +
192 +bool RenderWidgetHostViewEfl::PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) {
193 +  return false;
194 +}
195 +
196 +bool RenderWidgetHostViewEfl::PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) {
197 +  return false;
198 +}
199 +
200 +bool RenderWidgetHostViewEfl::PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) {
201 +return false;
202 +}
203 +
204 +bool RenderWidgetHostViewEfl::PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) {
205 +  return false;
206 +}
207 +
208 +bool RenderWidgetHostViewEfl::PreserveWindowKeyDown(Evas_Event_Key_Down* event) {
209 +  return false;
210 +}
211 +
212 +bool RenderWidgetHostViewEfl::PreserveWindowKeyUp(Evas_Event_Key_Up* event) {
213 +  return false;
214 +}
215 +
216 +void RenderWidgetHostViewEfl::PreserveWindowFocusIn() {
217 +}
218 +
219 +void RenderWidgetHostViewEfl::PreserveWindowFocusOut() {
220 +}
221 +
222 +void RenderWidgetHostViewEfl::PreserveWindowShow() {
223 +}
224 +
225 +void RenderWidgetHostViewEfl::PreserveWindowHide() {
226 +}
227 +
228 +void RenderWidgetHostViewEfl::PreserveWindowMove(const gfx::Point& origin) {
229 +}
230 +
231 +void RenderWidgetHostViewEfl::PreserveWindowResize(const gfx::Size& size) {
232 +  SetSize(size);
233 +}
234 +
235 +void RenderWidgetHostViewEfl::PreserveWindowRepaint(const gfx::Rect& damage_rect) {
236 +  Paint(damage_rect);
237 +}
238 +
239 +bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
240 +  bool handled = true;
241 +  IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewEfl, message)
242 +    IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer,
243 +                        OnCreatePluginContainer)
244 +    IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
245 +                        OnDestroyPluginContainer)
246 +    IPC_MESSAGE_UNHANDLED(handled = false)
247 +  IPC_END_MESSAGE_MAP()
248 +  return handled;
249 +}
250 +
251 +void RenderWidgetHostViewEfl::InitAsChild(
252 +    gfx::NativeView parent_view) {
253 +  Evas_Object* elm_box = reinterpret_cast<Evas_Object*>(parent_view);
254 +  Evas* evas = evas_object_evas_get(elm_box);
255 +  preserve_window_ = gfx::PreserveWindow::Create(this, evas);
256 +  evas_object_size_hint_align_set(preserve_window_->SmartObject(), EVAS_HINT_FILL, EVAS_HINT_FILL);
257 +  evas_object_size_hint_weight_set(preserve_window_->SmartObject(), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
258 +  elm_box_pack_end(elm_box, preserve_window_->SmartObject());
259 +  evas_object_show(preserve_window_->SmartObject());
260 +  compositing_surface_ = elm_win_xwindow_get(preserve_window_->EvasWindow());
261 +}
262 +
263 +void RenderWidgetHostViewEfl::InitAsPopup(
264 +    RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
265 +  // If we aren't a popup, then |window| will be leaked.
266 +  DCHECK(IsPopup());
267 +}
268 +
269 +void RenderWidgetHostViewEfl::InitAsFullscreen(
270 +    RenderWidgetHostView* reference_host_view) {
271 +  DCHECK(reference_host_view);
272 +}
273 +
274 +RenderWidgetHost* RenderWidgetHostViewEfl::GetRenderWidgetHost() const {
275 +  return host_;
276 +}
277 +
278 +void RenderWidgetHostViewEfl::WasShown() {
279 +  if (!is_hidden_)
280 +    return;
281 +
282 +  if (web_contents_switch_paint_time_.is_null())
283 +    web_contents_switch_paint_time_ = base::TimeTicks::Now();
284 +  is_hidden_ = false;
285 +  host_->WasShown();
286 +}
287 +
288 +void RenderWidgetHostViewEfl::WasHidden() {
289 +  if (is_hidden_)
290 +    return;
291 +
292 +  // If we receive any more paint messages while we are hidden, we want to
293 +  // ignore them so we don't re-allocate the backing store.  We will paint
294 +  // everything again when we become selected again.
295 +  is_hidden_ = true;
296 +
297 +  // If we have a renderer, then inform it that we are being hidden so it can
298 +  // reduce its resource utilization.
299 +  host_->WasHidden();
300 +
301 +  web_contents_switch_paint_time_ = base::TimeTicks();
302 +}
303 +
304 +void RenderWidgetHostViewEfl::SetSize(const gfx::Size& size) {
305 +  int width = std::min(size.width(), kMaxWindowWidth);
306 +  int height = std::min(size.height(), kMaxWindowHeight);
307 +  if (IsPopup()) {
308 +    // We're a popup, honor the size request.
309 +  }
310 +
311 +  // Update the size of the RWH.
312 +  if (requested_size_.width() != width ||
313 +      requested_size_.height() != height) {
314 +    requested_size_ = gfx::Size(width, height);
315 +    host_->SendScreenRects();
316 +    host_->WasResized();
317 +  }
318 +}
319 +
320 +void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
321 +  SetSize(rect.size());
322 +}
323 +
324 +gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
325 +  return reinterpret_cast<gfx::NativeView>(preserve_window_->SmartObject());
326 +}
327 +
328 +gfx::NativeViewId RenderWidgetHostViewEfl::GetNativeViewId() const {
329 +  return 0;
330 +}
331 +
332 +gfx::NativeViewAccessible RenderWidgetHostViewEfl::GetNativeViewAccessible() {
333 +  NOTIMPLEMENTED();
334 +  return NULL;
335 +}
336 +
337 +void RenderWidgetHostViewEfl::MovePluginWindows(
338 +    const gfx::Vector2d& scroll_offset,
339 +    const std::vector<webkit::npapi::WebPluginGeometry>& moves) {
340 +}
341 +
342 +void RenderWidgetHostViewEfl::Focus() {
343 +}
344 +
345 +void RenderWidgetHostViewEfl::Blur() {
346 +  // TODO(estade): We should be clearing native focus as well, but I know of no
347 +  // way to do that without focusing another widget.
348 +  host_->Blur();
349 +}
350 +
351 +bool RenderWidgetHostViewEfl::HasFocus() const {
352 +  return true;
353 +}
354 +
355 +void RenderWidgetHostViewEfl::ActiveWindowChanged(GdkWindow* window) {
356 +}
357 +
358 +bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
359 +  return host_->Send(message);
360 +}
361 +
362 +bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
363 +  return true;
364 +}
365 +
366 +void RenderWidgetHostViewEfl::Show() {
367 +}
368 +
369 +void RenderWidgetHostViewEfl::Hide() {
370 +}
371 +
372 +bool RenderWidgetHostViewEfl::IsShowing() {
373 +  return true;
374 +}
375 +
376 +gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
377 +  return gfx::Rect(requested_size_);
378 +}
379 +
380 +void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& cursor) {
381 +  // Optimize the common case, where the cursor hasn't changed.
382 +  // However, we can switch between different pixmaps, so only on the
383 +  // non-pixmap branch.
384 +  if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
385 +      current_cursor_.GetCursorType() == cursor.GetCursorType()) {
386 +    return;
387 +  }
388 +
389 +  current_cursor_ = cursor;
390 +  ShowCurrentCursor();
391 +}
392 +
393 +void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
394 +  is_loading_ = is_loading;
395 +  // Only call ShowCurrentCursor() when it will actually change the cursor.
396 +  if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
397 +    ShowCurrentCursor();
398 +}
399 +
400 +void RenderWidgetHostViewEfl::TextInputStateChanged(
401 +    const ViewHostMsg_TextInputState_Params& params) {
402 +}
403 +
404 +void RenderWidgetHostViewEfl::ImeCancelComposition() {
405 +}
406 +
407 +void RenderWidgetHostViewEfl::ImeCompositionRangeChanged(
408 +    const ui::Range& range,
409 +    const std::vector<gfx::Rect>& character_bounds) {
410 +}
411 +
412 +void RenderWidgetHostViewEfl::DidUpdateBackingStore(
413 +    const gfx::Rect& scroll_rect,
414 +    const gfx::Vector2d& scroll_delta,
415 +    const std::vector<gfx::Rect>& copy_rects) {
416 +  TRACE_EVENT0("ui::efl", "RenderWidgetHostViewEfl::DidUpdateBackingStore");
417 +
418 +  if (is_hidden_)
419 +    return;
420 +
421 +  // TODO(darin): Implement the equivalent of Win32's ScrollWindowEX.  Can that
422 +  // be done using XCopyArea?  Perhaps similar to
423 +  // BackingStore::ScrollBackingStore?
424 +  if (about_to_validate_and_paint_)
425 +    invalid_rect_.Union(scroll_rect);
426 +  else
427 +    Paint(scroll_rect);
428 +
429 +  for (size_t i = 0; i < copy_rects.size(); ++i) {
430 +    // Avoid double painting.  NOTE: This is only relevant given the call to
431 +    // Paint(scroll_rect) above.
432 +    gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
433 +    if (rect.IsEmpty())
434 +      continue;
435 +
436 +    if (about_to_validate_and_paint_)
437 +      invalid_rect_.Union(rect);
438 +    else
439 +      Paint(rect);
440 +  }
441 +}
442 +
443 +void RenderWidgetHostViewEfl::RenderViewGone(base::TerminationStatus status,
444 +                                             int error_code) {
445 +  Destroy();
446 +}
447 +
448 +void RenderWidgetHostViewEfl::Destroy() {
449 +  if (compositing_surface_ != gfx::kNullPluginWindow) {
450 +  }
451 +  if (do_x_grab_) {
452 +    // Undo the X grab.
453 +  }
454 +
455 +  if (preserve_window_->SmartObject()) {
456 +    // If this is a popup or fullscreen widget, then we need to destroy the
457 +    // window that we created to hold it.
458 +    if (IsPopup() || is_fullscreen_) {
459 +      ui::ActiveWindowWatcherX::RemoveObserver(this);
460 +    }
461 +    // See http://crbug.com/11847 for details.
462 +  }
463 +  // The RenderWidgetHost's destruction led here, so don't call it.
464 +  host_ = NULL;
465 +
466 +  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
467 +}
468 +
469 +void RenderWidgetHostViewEfl::SetTooltipText(const string16& tooltip_text) {
470 +  // I filed https://bugzilla.gnome.org/show_bug.cgi?id=604641 upstream.
471 +}
472 +
473 +void RenderWidgetHostViewEfl::SelectionChanged(const string16& text,
474 +                                               size_t offset,
475 +                                               const ui::Range& range) {
476 +  RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
477 +
478 +  if (text.empty() || range.is_empty())
479 +    return;
480 +  size_t pos = range.GetMin() - offset;
481 +  size_t n = range.length();
482 +
483 +  DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
484 +  if (pos >= text.length()) {
485 +    NOTREACHED() << "The text can not cover range.";
486 +    return;
487 +  }
488 +
489 +  BrowserContext* browser_context = host_->GetProcess()->GetBrowserContext();
490 +  // Set the BUFFER_SELECTION to the ui::Clipboard.
491 +  ui::ScopedClipboardWriter clipboard_writer(
492 +      ui::Clipboard::GetForCurrentThread(),
493 +      ui::Clipboard::BUFFER_SELECTION,
494 +      BrowserContext::GetMarkerForOffTheRecordContext(browser_context));
495 +  clipboard_writer.WriteText(text.substr(pos, n));
496 +}
497 +
498 +void RenderWidgetHostViewEfl::SelectionBoundsChanged(
499 +    const ViewHostMsg_SelectionBounds_Params& params) {
500 +}
501 +
502 +void RenderWidgetHostViewEfl::ScrollOffsetChanged() {
503 +}
504 +
505 +GdkEventButton* RenderWidgetHostViewEfl::GetLastMouseDown() {
506 +  return 0;
507 +}
508 +
509 +gfx::NativeView RenderWidgetHostViewEfl::BuildInputMethodsGtkMenu() {
510 +  return 0;
511 +}
512 +
513 +bool RenderWidgetHostViewEfl::NeedsInputGrab() {
514 +  return popup_type_ == WebKit::WebPopupTypeSelect;
515 +}
516 +
517 +bool RenderWidgetHostViewEfl::IsPopup() const {
518 +  return popup_type_ != WebKit::WebPopupTypeNone;
519 +}
520 +
521 +void RenderWidgetHostViewEfl::DoSharedInit(Evas_Object* parent) {
522 +}
523 +
524 +void RenderWidgetHostViewEfl::DoPopupOrFullscreenInit(GtkWindow* window,
525 +                                                      const gfx::Rect& bounds) {
526 +}
527 +
528 +BackingStore* RenderWidgetHostViewEfl::AllocBackingStore(
529 +    const gfx::Size& /*size*/) {
530 +  return 0;  // We're using accelerated path.
531 +}
532 +
533 +void RenderWidgetHostViewEfl::CopyFromCompositingSurface(
534 +    const gfx::Rect& src_subrect,
535 +    const gfx::Size& /* dst_size */,
536 +    const base::Callback<void(bool, const SkBitmap&)>& callback) {
537 +  // Grab the snapshot from the renderer as that's the only reliable way to
538 +  // readback from the GPU for this platform right now.
539 +  GetRenderWidgetHost()->GetSnapshotFromRenderer(src_subrect, callback);
540 +}
541 +
542 +void RenderWidgetHostViewEfl::CopyFromCompositingSurfaceToVideoFrame(
543 +      const gfx::Rect& src_subrect,
544 +      const scoped_refptr<media::VideoFrame>& target,
545 +      const base::Callback<void(bool)>& callback) {
546 +  NOTIMPLEMENTED();
547 +  callback.Run(false);
548 +}
549 +
550 +bool RenderWidgetHostViewEfl::CanCopyToVideoFrame() const {
551 +  return false;
552 +}
553 +
554 +void RenderWidgetHostViewEfl::AcceleratedSurfaceBuffersSwapped(
555 +    const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
556 +    int gpu_host_id) {
557 +    AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
558 +    ack_params.sync_point = 0;
559 +    RenderWidgetHostImpl::AcknowledgeBufferPresent(
560 +      params.route_id, gpu_host_id, ack_params);
561 +}
562 +
563 +void RenderWidgetHostViewEfl::AcceleratedSurfacePostSubBuffer(
564 +    const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
565 +    int gpu_host_id) {
566 +    AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
567 +    ack_params.sync_point = 0;
568 +    RenderWidgetHostImpl::AcknowledgeBufferPresent(
569 +      params.route_id, gpu_host_id, ack_params);
570 +}
571 +
572 +void RenderWidgetHostViewEfl::AcceleratedSurfaceSuspend() {
573 +}
574 +
575 +void RenderWidgetHostViewEfl::AcceleratedSurfaceRelease() {
576 +}
577 +
578 +bool RenderWidgetHostViewEfl::HasAcceleratedSurface(
579 +      const gfx::Size& desired_size) {
580 +  // TODO(jbates) Implement this so this view can use GetBackingStore for both
581 +  // software and GPU frames. Defaulting to false just makes GetBackingStore
582 +  // only useable for software frames.
583 +  return false;
584 +}
585 +
586 +void RenderWidgetHostViewEfl::SetBackground(const SkBitmap& background) {
587 +  RenderWidgetHostViewBase::SetBackground(background);
588 +  Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
589 +}
590 +
591 +void RenderWidgetHostViewEfl::ModifyEventForEdgeDragging(
592 +    GtkWidget* widget, GdkEventMotion* event) {
593 +  // If the widget is aligned with an edge of the monitor its on and the user
594 +  // attempts to drag past that edge we track the number of times it has
595 +  // occurred, so that we can force the widget to scroll when it otherwise
596 +  // would be unable to, by modifying the (x,y) position in the drag
597 +  // event that we forward on to webkit. If we get a move that's no longer a
598 +  // drag or a drag indicating the user is no longer at that edge we stop
599 +  // altering the drag events.
600 +  int new_dragged_at_horizontal_edge = 0;
601 +  int new_dragged_at_vertical_edge = 0;
602 +  // Used for checking the edges of the monitor. We cache the values to save
603 +  // roundtrips to the X server.
604 +  CR_DEFINE_STATIC_LOCAL(gfx::Size, drag_monitor_size, ());
605 +  if (event->state & GDK_BUTTON1_MASK) {
606 +    if (drag_monitor_size.IsEmpty()) {
607 +      // We can safely cache the monitor size for the duration of a drag.
608 +      GdkScreen* screen = gtk_widget_get_screen(widget);
609 +      int monitor =
610 +          gdk_screen_get_monitor_at_point(screen, event->x_root, event->y_root);
611 +      GdkRectangle geometry;
612 +      gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
613 +      drag_monitor_size.SetSize(geometry.width, geometry.height);
614 +    }
615 +    GtkAllocation allocation;
616 +    gtk_widget_get_allocation(widget, &allocation);
617 +    // Check X and Y independently, as the user could be dragging into a corner.
618 +    if (event->x == 0 && event->x_root == 0) {
619 +      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ - 1;
620 +    } else if (allocation.width - 1 == static_cast<gint>(event->x) &&
621 +        drag_monitor_size.width() - 1 == static_cast<gint>(event->x_root)) {
622 +      new_dragged_at_horizontal_edge = dragged_at_horizontal_edge_ + 1;
623 +    }
624 +
625 +    if (event->y == 0 && event->y_root == 0) {
626 +      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ - 1;
627 +    } else if (allocation.height - 1 == static_cast<gint>(event->y) &&
628 +        drag_monitor_size.height() - 1 == static_cast<gint>(event->y_root)) {
629 +      new_dragged_at_vertical_edge = dragged_at_vertical_edge_ + 1;
630 +    }
631 +
632 +    event->x_root += new_dragged_at_horizontal_edge;
633 +    event->x += new_dragged_at_horizontal_edge;
634 +    event->y_root += new_dragged_at_vertical_edge;
635 +    event->y += new_dragged_at_vertical_edge;
636 +  } else {
637 +    // Clear whenever we get a non-drag mouse move.
638 +    drag_monitor_size.SetSize(0, 0);
639 +  }
640 +  dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge;
641 +  dragged_at_vertical_edge_ = new_dragged_at_vertical_edge;
642 +}
643 +
644 +void RenderWidgetHostViewEfl::Paint(const gfx::Rect& /*damage_rect*/) {
645 +  // If the GPU process is rendering directly into the View,
646 +  // call the compositor directly.
647 +  host_->ScheduleComposite();
648 +}
649 +
650 +void RenderWidgetHostViewEfl::ShowCurrentCursor() {
651 +}
652 +
653 +void RenderWidgetHostViewEfl::SetHasHorizontalScrollbar(
654 +    bool has_horizontal_scrollbar) {
655 +}
656 +
657 +void RenderWidgetHostViewEfl::SetScrollOffsetPinning(
658 +    bool is_pinned_to_left, bool is_pinned_to_right) {
659 +}
660 +
661 +void RenderWidgetHostViewEfl::OnAcceleratedCompositingStateChange() {
662 +}
663 +
664 +void RenderWidgetHostViewEfl::GetScreenInfo(WebScreenInfo* results) {
665 +  content::GetScreenInfoEfl(results);
666 +}
667 +
668 +gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
669 +  return GetViewBounds();
670 +}
671 +
672 +gfx::GLSurfaceHandle RenderWidgetHostViewEfl::GetCompositingSurface() {
673 +  return gfx::GLSurfaceHandle(compositing_surface_, gfx::NATIVE_TRANSPORT);
674 +}
675 +
676 +bool RenderWidgetHostViewEfl::LockMouse() {
677 +  return false;
678 +}
679 +
680 +void RenderWidgetHostViewEfl::UnlockMouse() {
681 +}
682 +
683 +void RenderWidgetHostViewEfl::ForwardKeyboardEvent(
684 +    const NativeWebKeyboardEvent& event) {
685 +}
686 +
687 +bool RenderWidgetHostViewEfl::RetrieveSurrounding(std::string* text,
688 +                                                  size_t* cursor_index) {
689 +  if (!selection_range_.IsValid())
690 +    return false;
691 +
692 +  size_t offset = selection_range_.GetMin() - selection_text_offset_;
693 +  DCHECK(offset <= selection_text_.length());
694 +
695 +  if (offset == selection_text_.length()) {
696 +    *text = UTF16ToUTF8(selection_text_);
697 +    *cursor_index = text->length();
698 +    return true;
699 +  }
700 +
701 +  *text = base::UTF16ToUTF8AndAdjustOffset(
702 +      base::StringPiece16(selection_text_), &offset);
703 +  if (offset == string16::npos) {
704 +    NOTREACHED() << "Invalid offset in UTF16 string.";
705 +    return false;
706 +  }
707 +  *cursor_index = offset;
708 +  return true;
709 +}
710 +
711 +void RenderWidgetHostViewEfl::MarkCachedWidgetCenterStale() {
712 +  widget_center_valid_ = false;
713 +  mouse_has_been_warped_to_new_center_ = false;
714 +}
715 +
716 +gfx::Point RenderWidgetHostViewEfl::GetWidgetCenter() {
717 +  return gfx::Point();
718 +}
719 +
720 +void RenderWidgetHostViewEfl::ModifyEventMovementAndCoords(
721 +    WebKit::WebMouseEvent* event) {
722 +  // Movement is computed by taking the difference of the new cursor position
723 +  // and the previous. Under mouse lock the cursor will be warped back to the
724 +  // center so that we are not limited by clipping boundaries.
725 +  // We do not measure movement as the delta from cursor to center because
726 +  // we may receive more mouse movement events before our warp has taken
727 +  // effect.
728 +  event->movementX = event->globalX - global_mouse_position_.x();
729 +  event->movementY = event->globalY - global_mouse_position_.y();
730 +
731 +  // While the cursor is being warped back to the unlocked position, suppress
732 +  // the movement member data.
733 +  if (mouse_is_being_warped_to_unlocked_position_) {
734 +    event->movementX = 0;
735 +    event->movementY = 0;
736 +    if (MovedToPoint(*event, unlocked_global_mouse_position_))
737 +      mouse_is_being_warped_to_unlocked_position_ = false;
738 +  }
739 +
740 +  global_mouse_position_.SetPoint(event->globalX, event->globalY);
741 +
742 +  // Under mouse lock, coordinates of mouse are locked to what they were when
743 +  // mouse lock was entered.
744 +  if (mouse_locked_) {
745 +    event->x = unlocked_mouse_position_.x();
746 +    event->y = unlocked_mouse_position_.y();
747 +    event->windowX = unlocked_mouse_position_.x();
748 +    event->windowY = unlocked_mouse_position_.y();
749 +    event->globalX = unlocked_global_mouse_position_.x();
750 +    event->globalY = unlocked_global_mouse_position_.y();
751 +  } else {
752 +    unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
753 +    unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
754 +  }
755 +}
756 +
757 +////////////////////////////////////////////////////////////////////////////////
758 +// RenderWidgetHostView, public:
759 +
760 +// static
761 +RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
762 +    RenderWidgetHost* widget) {
763 +  return new RenderWidgetHostViewEfl(widget);
764 +}
765 +
766 +// static
767 +void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
768 +}
769 +
770 +void RenderWidgetHostViewEfl::SetAccessibilityFocus(int acc_obj_id) {
771 +  if (!host_)
772 +    return;
773 +  host_->AccessibilitySetFocus(acc_obj_id);
774 +}
775 +
776 +void RenderWidgetHostViewEfl::AccessibilityDoDefaultAction(int acc_obj_id) {
777 +  if (!host_)
778 +    return;
779 +  host_->AccessibilityDoDefaultAction(acc_obj_id);
780 +}
781 +
782 +void RenderWidgetHostViewEfl::AccessibilityScrollToMakeVisible(
783 +    int acc_obj_id, gfx::Rect subfocus) {
784 +  if (!host_)
785 +    return;
786 +
787 +  host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
788 +}
789 +
790 +void RenderWidgetHostViewEfl::AccessibilityScrollToPoint(
791 +    int acc_obj_id, gfx::Point point) {
792 +  if (!host_)
793 +    return;
794 +  host_->AccessibilityScrollToPoint(acc_obj_id, point);
795 +}
796 +
797 +void RenderWidgetHostViewEfl::AccessibilitySetTextSelection(
798 +    int acc_obj_id, int start_offset, int end_offset) {
799 +  if (!host_)
800 +    return;
801 +
802 +  host_->AccessibilitySetTextSelection(acc_obj_id, start_offset, end_offset);
803 +}
804 +
805 +gfx::Point RenderWidgetHostViewEfl::GetLastTouchEventLocation() const {
806 +  return gfx::Point();
807 +}
808 +
809 +void RenderWidgetHostViewEfl::FatalAccessibilityTreeError() {
810 +  if (host_) {
811 +    host_->FatalAccessibilityTreeError();
812 +    SetBrowserAccessibilityManager(NULL);
813 +  } else {
814 +    CHECK(FALSE);
815 +  }
816 +}
817 +
818 +void RenderWidgetHostViewEfl::OnAccessibilityNotifications(
819 +    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
820 +}
821 +
822 +AtkObject* RenderWidgetHostViewEfl::GetAccessible() {
823 +  return 0;
824 +}
825 +
826 +void RenderWidgetHostViewEfl::OnCreatePluginContainer(
827 +    gfx::PluginWindowHandle id) {
828 +}
829 +
830 +void RenderWidgetHostViewEfl::OnDestroyPluginContainer(
831 +    gfx::PluginWindowHandle id) {
832 +}
833 +
834 +}  // namespace content
835 diff --git a/content/browser/renderer_host/render_widget_host_view_efl.h b/content/browser/renderer_host/render_widget_host_view_efl.h
836 new file mode 100644
837 index 0000000..2aba48f
838 --- /dev/null
839 +++ b/content/browser/renderer_host/render_widget_host_view_efl.h
840 @@ -0,0 +1,317 @@
841 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
842 +// Use of this source code is governed by a BSD-style license that can be
843 +// found in the LICENSE file.
844 +
845 +#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
846 +#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
847 +
848 +#include <Evas.h>
849 +#include <gdk/gdk.h>
850 +
851 +#include <string>
852 +#include <vector>
853 +
854 +#include "base/memory/scoped_ptr.h"
855 +#include "base/time.h"
856 +#include "content/browser/accessibility/browser_accessibility_manager.h"
857 +#include "content/browser/renderer_host/render_widget_host_view_base.h"
858 +#include "content/common/content_export.h"
859 +#include "ipc/ipc_sender.h"
860 +#include "ui/base/animation/animation_delegate.h"
861 +#include "ui/base/animation/slide_animation.h"
862 +#include "ui/base/x/active_window_watcher_x_observer.h"
863 +#include "ui/gfx/native_widget_types.h"
864 +#include "ui/gfx/point.h"
865 +#include "ui/gfx/preserve_window_delegate_efl.h"
866 +#include "ui/gfx/rect.h"
867 +#include "webkit/glue/webcursor.h"
868 +#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
869 +
870 +typedef struct _GtkClipboard GtkClipboard;
871 +typedef struct _GtkSelectionData GtkSelectionData;
872 +
873 +namespace gfx {
874 +class PreserveWindow;
875 +}
876 +
877 +namespace content {
878 +class RenderWidgetHost;
879 +class RenderWidgetHostImpl;
880 +struct NativeWebKeyboardEvent;
881 +
882 +// -----------------------------------------------------------------------------
883 +// See comments in render_widget_host_view.h about this class and its members.
884 +// -----------------------------------------------------------------------------
885 +class CONTENT_EXPORT RenderWidgetHostViewEfl
886 +    : public gfx::PreserveWindowDelegate,
887 +      public RenderWidgetHostViewBase,
888 +      public BrowserAccessibilityDelegate,
889 +      public ui::ActiveWindowWatcherXObserver,
890 +      public IPC::Sender {
891 + public:
892 +  virtual ~RenderWidgetHostViewEfl();
893 +
894 +  // PreserveWindowDelegate implementation.
895 +  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event);
896 +  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event);
897 +  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event);
898 +  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event);
899 +  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event);
900 +  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event);
901 +  virtual void PreserveWindowFocusIn();
902 +  virtual void PreserveWindowFocusOut();
903 +  virtual void PreserveWindowShow();
904 +  virtual void PreserveWindowHide();
905 +  virtual void PreserveWindowMove(const gfx::Point& origin);
906 +  virtual void PreserveWindowResize(const gfx::Size& size);
907 +  virtual void PreserveWindowRepaint(const gfx::Rect& damage_rect);
908 +
909 +
910 +  // RenderWidgetHostView implementation.
911 +  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
912 +  virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
913 +  virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
914 +  virtual void SetSize(const gfx::Size& size) OVERRIDE;
915 +  virtual void SetBounds(const gfx::Rect& rect) OVERRIDE;
916 +  virtual gfx::NativeView GetNativeView() const OVERRIDE;
917 +  virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
918 +  virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
919 +  virtual bool HasFocus() const OVERRIDE;
920 +  virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
921 +  virtual void Show() OVERRIDE;
922 +  virtual void Hide() OVERRIDE;
923 +  virtual bool IsShowing() OVERRIDE;
924 +  virtual gfx::Rect GetViewBounds() const OVERRIDE;
925 +  virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
926 +  virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
927 +  virtual void SetBackground(const SkBitmap& background) OVERRIDE;
928 +
929 +  // RenderWidgetHostViewPort implementation.
930 +  virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
931 +                           const gfx::Rect& pos) OVERRIDE;
932 +  virtual void InitAsFullscreen(
933 +      RenderWidgetHostView* reference_host_view) OVERRIDE;
934 +  virtual void WasShown() OVERRIDE;
935 +  virtual void WasHidden() OVERRIDE;
936 +  virtual void MovePluginWindows(
937 +      const gfx::Vector2d& scroll_offset,
938 +      const std::vector<webkit::npapi::WebPluginGeometry>& moves) OVERRIDE;
939 +  virtual void Focus() OVERRIDE;
940 +  virtual void Blur() OVERRIDE;
941 +  virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE;
942 +  virtual void SetIsLoading(bool is_loading) OVERRIDE;
943 +  virtual void TextInputStateChanged(
944 +      const ViewHostMsg_TextInputState_Params& params) OVERRIDE;
945 +  virtual void ImeCancelComposition() OVERRIDE;
946 +  virtual void ImeCompositionRangeChanged(
947 +      const ui::Range& range,
948 +      const std::vector<gfx::Rect>& character_bounds) OVERRIDE;
949 +  virtual void DidUpdateBackingStore(
950 +      const gfx::Rect& scroll_rect,
951 +      const gfx::Vector2d& scroll_delta,
952 +      const std::vector<gfx::Rect>& copy_rects) OVERRIDE;
953 +  virtual void RenderViewGone(base::TerminationStatus status,
954 +                              int error_code) OVERRIDE;
955 +  virtual void Destroy() OVERRIDE;
956 +  virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
957 +  virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
958 +  virtual void SelectionChanged(const string16& text,
959 +                                size_t offset,
960 +                                const ui::Range& range) OVERRIDE;
961 +  virtual void SelectionBoundsChanged(
962 +      const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
963 +  virtual void ScrollOffsetChanged() OVERRIDE;
964 +  virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
965 +  virtual void CopyFromCompositingSurface(
966 +      const gfx::Rect& src_subrect,
967 +      const gfx::Size& dst_size,
968 +      const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE;
969 +  virtual void CopyFromCompositingSurfaceToVideoFrame(
970 +      const gfx::Rect& src_subrect,
971 +      const scoped_refptr<media::VideoFrame>& target,
972 +      const base::Callback<void(bool)>& callback) OVERRIDE;
973 +  virtual bool CanCopyToVideoFrame() const OVERRIDE;
974 +  virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
975 +  virtual void AcceleratedSurfaceBuffersSwapped(
976 +      const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
977 +      int gpu_host_id) OVERRIDE;
978 +  virtual void AcceleratedSurfacePostSubBuffer(
979 +      const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
980 +      int gpu_host_id) OVERRIDE;
981 +  virtual void AcceleratedSurfaceSuspend() OVERRIDE;
982 +  virtual void AcceleratedSurfaceRelease() OVERRIDE;
983 +  virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
984 +  virtual void SetHasHorizontalScrollbar(
985 +      bool has_horizontal_scrollbar) OVERRIDE;
986 +  virtual void SetScrollOffsetPinning(
987 +      bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE;
988 +  virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
989 +  virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
990 +  virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
991 +  virtual bool LockMouse() OVERRIDE;
992 +  virtual void UnlockMouse() OVERRIDE;
993 +  virtual void OnAccessibilityNotifications(
994 +      const std::vector<AccessibilityHostMsg_NotificationParams>& params)
995 +      OVERRIDE;
996 +
997 +  // ActiveWindowWatcherXObserver implementation.
998 +  virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
999 +
1000 +  // IPC::Sender implementation:
1001 +  virtual bool Send(IPC::Message* message) OVERRIDE;
1002 +
1003 +  void ModifyEventForEdgeDragging(GtkWidget* widget, GdkEventMotion* event);
1004 +
1005 +  void ModifyEventMovementAndCoords(WebKit::WebMouseEvent* event);
1006 +
1007 +  void Paint(const gfx::Rect&);
1008 +
1009 +  void ForwardKeyboardEvent(const NativeWebKeyboardEvent& event);
1010 +
1011 +  bool RetrieveSurrounding(std::string* text, size_t* cursor_index);
1012 +
1013 +  // BrowserAccessibilityDelegate implementation.
1014 +  virtual void SetAccessibilityFocus(int acc_obj_id) OVERRIDE;
1015 +  virtual void AccessibilityDoDefaultAction(int acc_obj_id) OVERRIDE;
1016 +  virtual void AccessibilityScrollToMakeVisible(
1017 +      int acc_obj_id, gfx::Rect subfocus) OVERRIDE;
1018 +  virtual void AccessibilityScrollToPoint(
1019 +      int acc_obj_id, gfx::Point point) OVERRIDE;
1020 +  virtual void AccessibilitySetTextSelection(
1021 +      int acc_obj_id, int start_offset, int end_offset) OVERRIDE;
1022 +  virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE;
1023 +  virtual void FatalAccessibilityTreeError() OVERRIDE;
1024 +
1025 +  // Get the root of the AtkObject* tree for accessibility.
1026 +  AtkObject* GetAccessible();
1027 +
1028 + protected:
1029 +  friend class RenderWidgetHostView;
1030 +
1031 +  // Should construct only via RenderWidgetHostView::CreateViewForWidget.
1032 +  explicit RenderWidgetHostViewEfl(RenderWidgetHost* widget);
1033 +
1034 + private:
1035 +  // Returns whether the widget needs an input grab (GTK+ and X) to work
1036 +  // properly.
1037 +  bool NeedsInputGrab();
1038 +
1039 +  // Returns whether this render view is a popup (<select> dropdown or
1040 +  // autocomplete window).
1041 +  bool IsPopup() const;
1042 +
1043 +  // Do initialization needed by all InitAs*() methods.
1044 +  void DoSharedInit(Evas_Object* parent);
1045 +
1046 +  // Do initialization needed just by InitAsPopup() and InitAsFullscreen().
1047 +  // We move and resize |window| to |bounds| and show it and its contents.
1048 +  void DoPopupOrFullscreenInit(GtkWindow* window, const gfx::Rect& bounds);
1049 +
1050 +  // Update the display cursor for the render view.
1051 +  void ShowCurrentCursor();
1052 +
1053 +  // Cause the next query for the widget center to recompute the cached value.
1054 +  void MarkCachedWidgetCenterStale();
1055 +
1056 +  void OnCreatePluginContainer(gfx::PluginWindowHandle id);
1057 +  void OnDestroyPluginContainer(gfx::PluginWindowHandle id);
1058 +
1059 +  gfx::Point GetWidgetCenter();
1060 +
1061 +  // The model object.
1062 +  RenderWidgetHostImpl* host_;
1063 +
1064 +  // This is true when we are currently painting and thus should handle extra
1065 +  // paint requests by expanding the invalid rect rather than actually
1066 +  // painting.
1067 +  bool about_to_validate_and_paint_;
1068 +
1069 +  // This is the rectangle which we'll paint.
1070 +  gfx::Rect invalid_rect_;
1071 +
1072 +  // Whether or not this widget is hidden.
1073 +  bool is_hidden_;
1074 +
1075 +  // Whether we are currently loading.
1076 +  bool is_loading_;
1077 +
1078 +  // The cursor for the page. This is passed up from the renderer.
1079 +  WebCursor current_cursor_;
1080 +
1081 +  // The time at which this view started displaying white pixels as a result of
1082 +  // not having anything to paint (empty backing store from renderer). This
1083 +  // value returns true for is_null() if we are not recording whiteout times.
1084 +  base::TimeTicks whiteout_start_time_;
1085 +
1086 +  // The time it took after this view was selected for it to be fully painted.
1087 +  base::TimeTicks web_contents_switch_paint_time_;
1088 +
1089 +  // The native view of our parent widget.  Used only for popups.
1090 +  Evas_Object* parent_;
1091 +
1092 +  // We ignore the first mouse release on popups so the popup will remain open.
1093 +  bool is_popup_first_mouse_release_;
1094 +
1095 +  // Whether or not this widget's input context was focused before being
1096 +  // shadowed by another widget. Used in OnGrabNotify() handler to track the
1097 +  // focused state correctly.
1098 +  bool was_imcontext_focused_before_grab_;
1099 +
1100 +  // True if we are responsible for creating an X grab. This will only be used
1101 +  // for <select> dropdowns. It should be true for most such cases, but false
1102 +  // for extension popups.
1103 +  bool do_x_grab_;
1104 +
1105 +  // Is the widget fullscreen?
1106 +  bool is_fullscreen_;
1107 +
1108 +  // Has the window ever been marked active? Only valid for fullscreen or
1109 +  // popup windows.
1110 +  bool made_active_;
1111 +
1112 +  // Used to record the last position of the mouse.
1113 +  // While the mouse is locked, they store the last known position just as mouse
1114 +  // lock was entered.
1115 +  // Relative to the upper-left corner of the view.
1116 +  gfx::Point unlocked_mouse_position_;
1117 +  // Relative to the upper-left corner of the screen.
1118 +  gfx::Point unlocked_global_mouse_position_;
1119 +  // Last hidden cursor position. Relative to screen.
1120 +  gfx::Point global_mouse_position_;
1121 +  // Indicates when mouse motion is valid after the widget has moved.
1122 +  bool mouse_has_been_warped_to_new_center_;
1123 +  // Indicates the cursor has been warped to the unlocked position,
1124 +  // but a move event has not yet been received for it there.
1125 +  bool mouse_is_being_warped_to_unlocked_position_;
1126 +
1127 +  // For full-screen windows we have a OnDestroy handler that we need to remove,
1128 +  // so we keep it ID here.
1129 +  unsigned long destroy_handler_id_;
1130 +
1131 +  gfx::Size requested_size_;
1132 +
1133 +  // The latest reported center of the widget, use GetWidgetCenter() to access.
1134 +  gfx::Point widget_center_;
1135 +  // If the window moves the widget_center will not be valid until we recompute.
1136 +  bool widget_center_valid_;
1137 +
1138 +  // The number of times the user has dragged against horizontal edge  of the
1139 +  // monitor (if the widget is aligned with that edge). Negative values
1140 +  // indicate the left edge, positive the right.
1141 +  int dragged_at_horizontal_edge_;
1142 +
1143 +  // The number of times the user has dragged against vertical edge  of the
1144 +  // monitor (if the widget is aligned with that edge). Negative values
1145 +  // indicate the top edge, positive the bottom.
1146 +  int dragged_at_vertical_edge_;
1147 +
1148 +  gfx::PluginWindowHandle compositing_surface_;
1149 +
1150 +  gfx::PreserveWindow* preserve_window_;
1151 +
1152 +  scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
1153 +};
1154 +
1155 +}  // namespace content
1156 +
1157 +#endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_EFL_H_
1158 diff --git a/content/browser/renderer_host/window_utils_efl.cc b/content/browser/renderer_host/window_utils_efl.cc
1159 new file mode 100644
1160 index 0000000..1c6c511
1161 --- /dev/null
1162 +++ b/content/browser/renderer_host/window_utils_efl.cc
1163 @@ -0,0 +1,51 @@
1164 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1165 +// Use of this source code is governed by a BSD-style license that can be
1166 +// found in the LICENSE file.
1167 +
1168 +#include "content/browser/renderer_host/window_utils_efl.h"
1169 +
1170 +#include "ui/gfx/rect.h"
1171 +#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
1172 +
1173 +#include <Ecore_X.h>
1174 +
1175 +namespace content {
1176 +
1177 +namespace {
1178 +
1179 +// Length of an inch in CSS's 1px unit.
1180 +const int kPixelsPerInch = 96;
1181 +
1182 +int depthPerComponent(int depth)
1183 +{
1184 +    switch (depth) {
1185 +    case 0:
1186 +    case 24:
1187 +    case 32:
1188 +        return 8;
1189 +    case 8:
1190 +        return 2;
1191 +    default:
1192 +        return depth / 3;
1193 +    }
1194 +}
1195 +
1196 +}
1197 +
1198 +void GetScreenInfoEfl(WebKit::WebScreenInfo* results)
1199 +{
1200 +  Ecore_X_Display* display = ecore_x_display_get();
1201 +  Ecore_X_Screen* screen = ecore_x_default_screen_get();
1202 +  int width, height;
1203 +  ecore_x_screen_size_get(screen, &width, &height);
1204 +  int depth = ecore_x_default_depth_get(display, screen);
1205 +  results->deviceScaleFactor = ecore_x_dpi_get() / kPixelsPerInch;
1206 +  results->isMonochrome = depth == 1;
1207 +  results->depth = depth;
1208 +  results->depthPerComponent = depthPerComponent(depth);
1209 +  // FIXME: not sure how to get available rect.
1210 +  results->rect = WebKit::WebRect(0, 0, width, height);
1211 +  results->availableRect = results->rect;
1212 +}
1213 +
1214 +} // namespace content
1215 diff --git a/content/browser/renderer_host/window_utils_efl.h b/content/browser/renderer_host/window_utils_efl.h
1216 new file mode 100644
1217 index 0000000..1df0e51
1218 --- /dev/null
1219 +++ b/content/browser/renderer_host/window_utils_efl.h
1220 @@ -0,0 +1,20 @@
1221 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1222 +// Use of this source code is governed by a BSD-style license that can be
1223 +// found in the LICENSE file.
1224 +
1225 +#ifndef CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
1226 +#define CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
1227 +
1228 +#include "content/common/content_export.h"
1229 +
1230 +namespace WebKit {
1231 +struct WebScreenInfo;
1232 +}
1233 +
1234 +namespace content {
1235 +
1236 +CONTENT_EXPORT void GetScreenInfoEfl(WebKit::WebScreenInfo* results);
1237 +
1238 +}  // namespace content
1239 +
1240 +#endif  // CONTENT_BROWSER_RENDERER_HOST_WINDOW_UTILS_EFL_H_
1241 diff --git a/content/browser/web_contents/web_contents_view_efl.cc b/content/browser/web_contents/web_contents_view_efl.cc
1242 index a3a4196..1e2edb8 100644
1243 --- a/content/browser/web_contents/web_contents_view_efl.cc
1244 +++ b/content/browser/web_contents/web_contents_view_efl.cc
1245 @@ -89,17 +89,15 @@ WebContentsViewEfl::WebContentsViewEfl(
1246      WebContentsImpl* web_contents,
1247      WebContentsViewDelegate* delegate)
1248      : web_contents_(web_contents),
1249 -      delegate_(delegate) {
1250 +      delegate_(delegate),
1251 +      view_container_box_(0) {
1252  }
1253  
1254  WebContentsViewEfl::~WebContentsViewEfl() {
1255  }
1256  
1257  gfx::NativeView WebContentsViewEfl::GetNativeView() const {
1258 -  if (delegate_)
1259 -    return delegate_->GetNativeView();
1260 -
1261 -  return 0;
1262 +  return GetContentNativeView();
1263  }
1264  
1265  gfx::NativeView WebContentsViewEfl::GetContentNativeView() const {
1266 @@ -173,7 +171,7 @@ RenderWidgetHostView* WebContentsViewEfl::CreateViewForWidget(
1267  
1268    RenderWidgetHostView* view =
1269        RenderWidgetHostView::CreateViewForWidget(render_widget_host);
1270 -  view->InitAsChild(NULL);
1271 +  view->InitAsChild(reinterpret_cast<gfx::NativeView>(view_container_box_));
1272    if (render_widget_host->IsRenderView()) {
1273      RenderViewHost* rvh = RenderViewHost::From(render_widget_host);
1274      if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
1275 diff --git a/content/browser/web_contents/web_contents_view_efl.h b/content/browser/web_contents/web_contents_view_efl.h
1276 index 495d4ff..3c6d2f6 100644
1277 --- a/content/browser/web_contents/web_contents_view_efl.h
1278 +++ b/content/browser/web_contents/web_contents_view_efl.h
1279 @@ -80,6 +80,8 @@ class CONTENT_EXPORT WebContentsViewEfl
1280    virtual void GotFocus() OVERRIDE;
1281    virtual void TakeFocus(bool reverse) OVERRIDE;
1282  
1283 +  void SetViewContainerBox(Evas_Object* container_box) { view_container_box_ = container_box; }
1284 +
1285   private:
1286    void UpdateDragDest(RenderViewHost* new_host);
1287  
1288 @@ -87,6 +89,10 @@ class CONTENT_EXPORT WebContentsViewEfl
1289  
1290    scoped_ptr<WebContentsViewDelegate> delegate_;
1291  
1292 +  Evas_Object* view_container_box_;
1293 +
1294 +  // The size we want the view to be.  We keep this in a separate variable
1295 +  // because resizing in GTK+ is async.
1296    gfx::Size requested_size_;
1297  
1298    DISALLOW_COPY_AND_ASSIGN(WebContentsViewEfl);
1299 diff --git a/content/content_browser.gypi b/content/content_browser.gypi
1300 index d087938..3d881a2 100644
1301 --- a/content/content_browser.gypi
1302 +++ b/content/content_browser.gypi
1303 @@ -827,6 +827,8 @@
1304      'browser/renderer_host/render_widget_host_view_aura.h',
1305      'browser/renderer_host/render_widget_host_view_base.cc',
1306      'browser/renderer_host/render_widget_host_view_base.h',
1307 +    'browser/renderer_host/render_widget_host_view_efl.cc',
1308 +    'browser/renderer_host/render_widget_host_view_efl.h',
1309      'browser/renderer_host/render_widget_host_view_gtk.cc',
1310      'browser/renderer_host/render_widget_host_view_gtk.h',
1311      'browser/renderer_host/render_widget_host_view_guest.cc',
1312 @@ -870,6 +872,8 @@
1313      'browser/renderer_host/web_input_event_aura.h',
1314      'browser/renderer_host/web_input_event_aurawin.cc',
1315      'browser/renderer_host/web_input_event_aurax11.cc',
1316 +    'browser/renderer_host/window_utils_efl.h',
1317 +    'browser/renderer_host/window_utils_efl.cc',
1318      'browser/resolve_proxy_msg_helper.cc',
1319      'browser/resolve_proxy_msg_helper.h',
1320      'browser/resource_context_impl.cc',
1321 @@ -1172,6 +1176,10 @@
1322        'sources/': [
1323          ['exclude', 'browser/web_contents/web_contents_view_gtk.cc'],
1324          ['exclude', 'browser/web_contents/web_contents_view_gtk.h'],
1325 +        ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.cc'],
1326 +        ['exclude', 'browser/renderer_host/render_widget_host_view_gtk.h'],
1327 +        ['exclude', 'browser/renderer_host/gtk_im_context_wrapper.cc'],
1328 +        ['exclude', 'browser/renderer_host/gtk_im_context_wrapper.h'],
1329        ]
1330      }],
1331      ['OS=="linux"', {
1332 diff --git a/content/content_shell.gypi b/content/content_shell.gypi
1333 index fc8b680..7ce351f 100644
1334 --- a/content/content_shell.gypi
1335 +++ b/content/content_shell.gypi
1336 @@ -137,6 +137,7 @@
1337          'shell/shell_web_contents_view_delegate_android.cc',
1338          'shell/shell_web_contents_view_delegate_creator.h',
1339          'shell/shell_web_contents_view_delegate_gtk.cc',
1340 +        'shell/shell_web_contents_view_delegate_efl.cc',
1341          'shell/shell_web_contents_view_delegate_mac.mm',
1342          'shell/shell_web_contents_view_delegate_win.cc',
1343          'shell/shell_web_contents_view_delegate.h',
1344 @@ -222,6 +223,7 @@
1345            ],
1346            'sources/': [
1347              ['exclude', 'shell/shell_gtk.cc'],
1348 +            ['exclude', 'shell/shell_web_contents_view_delegate_gtk.cc'],
1349            ],
1350          }],
1351          ['chromeos==1', {
1352 diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
1353 index 19822da..3078d63 100644
1354 --- a/content/shell/shell_efl.cc
1355 +++ b/content/shell/shell_efl.cc
1356 @@ -16,6 +16,7 @@
1357  #include "content/public/browser/native_web_keyboard_event.h"
1358  #include "content/public/browser/web_contents.h"
1359  #include "content/public/browser/web_contents_view.h"
1360 +#include "content/browser/web_contents/web_contents_view_efl.h"
1361  #include "content/public/common/renderer_preferences.h"
1362  #include "content/shell/shell_browser_context.h"
1363  #include "content/shell/shell_content_browser_client.h"
1364 @@ -51,22 +52,11 @@ void Shell::PlatformCreateWindow(int width, int height) {
1365    if (headless_)
1366      return;
1367  
1368 -  main_window_ = elm_win_add(NULL, "Content Shell", ELM_WIN_BASIC);
1369 -
1370 -  elm_win_title_set(main_window_, "Content Shell");
1371 +  main_window_ = elm_win_util_standard_add("Content Shell", "Content Shell");
1372    elm_win_autodel_set(main_window_, true);
1373 -
1374    evas_object_resize(main_window_, width, height);
1375    evas_object_event_callback_add(main_window_, EVAS_CALLBACK_DEL,
1376                                   OnMainWindowDel, this);
1377 -
1378 -  Evas_Object* rect = evas_object_rectangle_add(
1379 -      evas_object_evas_get(main_window_));
1380 -  evas_object_color_set(rect, 255, 0, 0, 255);
1381 -  evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1382 -  elm_win_resize_object_add(main_window_, rect);
1383 -  evas_object_show(rect);
1384 -
1385    evas_object_show(main_window_);
1386  }
1387  
1388 @@ -74,7 +64,13 @@ void Shell::PlatformSetContents() {
1389    if (headless_)
1390      return;
1391  
1392 +  Evas_Object* view_box = elm_box_add(main_window_);
1393 +  evas_object_size_hint_weight_set(view_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1394 +
1395 +  elm_win_resize_object_add(main_window_, view_box);
1396 +
1397    WebContentsView* content_view = web_contents_->GetView();
1398 +  static_cast<WebContentsViewEfl*>(content_view)->SetViewContainerBox(view_box);
1399  }
1400  
1401  void Shell::SizeTo(int width, int height) {
1402 diff --git a/content/shell/shell_web_contents_view_delegate.h b/content/shell/shell_web_contents_view_delegate.h
1403 index 283f37f..db6a785 100644
1404 --- a/content/shell/shell_web_contents_view_delegate.h
1405 +++ b/content/shell/shell_web_contents_view_delegate.h
1406 @@ -53,7 +53,7 @@ class ShellWebContentsViewDelegate : public WebContentsViewDelegate {
1407    WebContents* web_contents_;
1408    ContextMenuParams params_;
1409  
1410 -#if defined(TOOLKIT_GTK)
1411 +#if defined(TOOLKIT_GTK) && !defined(TOOLKIT_EFL)
1412    ui::OwnedWidgetGtk floating_;
1413    GtkWidget* expanded_container_;
1414  
1415 diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
1416 new file mode 100644
1417 index 0000000..9e10940
1418 --- /dev/null
1419 +++ b/content/shell/shell_web_contents_view_delegate_efl.cc
1420 @@ -0,0 +1,71 @@
1421 +// Copyright (c) 2013 Intel. All rights reserved.
1422 +// Use of this source code is governed by a BSD-style license that can be
1423 +// found in the LICENSE file.
1424 +
1425 +#include "content/shell/shell_web_contents_view_delegate.h"
1426 +
1427 +#include "base/command_line.h"
1428 +#include "content/public/browser/render_process_host.h"
1429 +#include "content/public/browser/render_view_host.h"
1430 +#include "content/public/browser/render_widget_host_view.h"
1431 +#include "content/public/browser/web_contents.h"
1432 +#include "content/public/browser/web_contents_view.h"
1433 +#include "content/public/common/context_menu_params.h"
1434 +#include "content/shell/shell.h"
1435 +#include "content/shell/shell_browser_context.h"
1436 +#include "content/shell/shell_browser_main_parts.h"
1437 +#include "content/shell/shell_content_browser_client.h"
1438 +#include "content/shell/shell_devtools_frontend.h"
1439 +#include "content/shell/shell_switches.h"
1440 +#include "content/shell/shell_web_contents_view_delegate_creator.h"
1441 +#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
1442 +#include "ui/base/gtk/focus_store_gtk.h"
1443 +#include "ui/base/gtk/gtk_floating_container.h"
1444 +
1445 +using WebKit::WebContextMenuData;
1446 +
1447 +namespace content {
1448 +
1449 +WebContentsViewDelegate* CreateShellWebContentsViewDelegate(
1450 +    WebContents* web_contents) {
1451 +  return new ShellWebContentsViewDelegate(web_contents);
1452 +}
1453 +
1454 +ShellWebContentsViewDelegate::ShellWebContentsViewDelegate(
1455 +    WebContents* web_contents)
1456 +    : web_contents_(web_contents) {
1457 +}
1458 +
1459 +ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() {
1460 +}
1461 +
1462 +void ShellWebContentsViewDelegate::ShowContextMenu(
1463 +    const ContextMenuParams& params,
1464 +    ContextMenuSourceType type) {
1465 +  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
1466 +    return;
1467 +}
1468 +
1469 +WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
1470 +  return NULL;
1471 +}
1472 +
1473 +void ShellWebContentsViewDelegate::Initialize(GtkWidget* expanded_container,
1474 +                                              ui::FocusStoreGtk* focus_store) {
1475 +}
1476 +
1477 +gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const {
1478 +  return 0;
1479 +}
1480 +
1481 +void ShellWebContentsViewDelegate::Focus() {
1482 +}
1483 +
1484 +gboolean ShellWebContentsViewDelegate::OnNativeViewFocusEvent(
1485 +    GtkWidget* widget,
1486 +    GtkDirectionType type,
1487 +    gboolean* return_value) {
1488 +  return false;
1489 +}
1490 +
1491 +}  // namespace content
1492 diff --git a/ui/gfx/efl_util.cc b/ui/gfx/efl_util.cc
1493 index 7cd7cb4..e207949 100644
1494 --- a/ui/gfx/efl_util.cc
1495 +++ b/ui/gfx/efl_util.cc
1496 @@ -18,12 +18,14 @@ void EflInit() {
1497    evas_init();
1498    ecore_init();
1499    ecore_evas_init();
1500 +  ecore_x_init(NULL);
1501    edje_init();
1502    ecore_main_loop_glib_integrate();
1503  }
1504  
1505  void EflShutdown() {
1506    edje_shutdown();
1507 +  ecore_x_shutdown();
1508    ecore_evas_shutdown();
1509    ecore_shutdown();
1510    evas_shutdown();
1511 diff --git a/ui/gfx/preserve_window_delegate_efl.h b/ui/gfx/preserve_window_delegate_efl.h
1512 new file mode 100644
1513 index 0000000..aa7863b
1514 --- /dev/null
1515 +++ b/ui/gfx/preserve_window_delegate_efl.h
1516 @@ -0,0 +1,47 @@
1517 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1518 +// Use of this source code is governed by a BSD-style license that can be
1519 +// found in the LICENSE file.
1520 +
1521 +#ifndef UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
1522 +#define UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
1523 +
1524 +#include <Evas.h>
1525 +
1526 +#include "ui/base/ui_export.h"
1527 +#include "ui/gfx/point.h"
1528 +#include "ui/gfx/rect.h"
1529 +#include "ui/gfx/size.h"
1530 +
1531 +namespace gfx {
1532 +
1533 +// A private interface used by RootWindowHost implementations to communicate input events
1534 +// with their owning PreserveWindow.
1535 +class UI_EXPORT PreserveWindowDelegate {
1536 + public:
1537 +  virtual bool PreserveWindowMouseDown(Evas_Event_Mouse_Down* event) = 0;
1538 +  virtual bool PreserveWindowMouseUp(Evas_Event_Mouse_Up* event) = 0;
1539 +  virtual bool PreserveWindowMouseMove(Evas_Event_Mouse_Move* event) = 0;
1540 +  virtual bool PreserveWindowMouseWheel(Evas_Event_Mouse_Wheel* event) = 0;
1541 +  virtual bool PreserveWindowKeyDown(Evas_Event_Key_Down* event) = 0;
1542 +  virtual bool PreserveWindowKeyUp(Evas_Event_Key_Up* event) = 0;
1543 +
1544 +  // Called when the windowing system activates the window.
1545 +  virtual void PreserveWindowFocusIn() = 0;
1546 +
1547 +  // Called when system focus is changed to another window.
1548 +  virtual void PreserveWindowFocusOut() = 0;
1549 +
1550 +  virtual void PreserveWindowShow() = 0;
1551 +  virtual void PreserveWindowHide() = 0;
1552 +
1553 +  virtual void PreserveWindowMove(const gfx::Point& origin) = 0;
1554 +  virtual void PreserveWindowResize(const gfx::Size& size) = 0;
1555 +  virtual void PreserveWindowRepaint(const gfx::Rect& damage_rect) = 0;
1556 +
1557 + protected:
1558 +  virtual ~PreserveWindowDelegate() {}
1559 +};
1560 +
1561 +}  // namespace gfx
1562 +
1563 +#endif  // UI_GFX_PRESERVE_WINDOW_DELEGATE_EFL_H_
1564 diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
1565 new file mode 100644
1566 index 0000000..4601099
1567 --- /dev/null
1568 +++ b/ui/gfx/preserve_window_efl.cc
1569 @@ -0,0 +1,421 @@
1570 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1571 +// Use of this source code is governed by a BSD-style license that can be
1572 +// found in the LICENSE file.
1573 +
1574 +#include "ui/gfx/preserve_window_efl.h"
1575 +
1576 +#include <Ecore.h>
1577 +#include <Ecore_Evas.h>
1578 +#include <Ecore_X.h>
1579 +#include <Elementary.h>
1580 +
1581 +#include "base/logging.h"
1582 +#include "ui/gfx/point.h"
1583 +#include "ui/gfx/rect.h"
1584 +#include "ui/gfx/size.h"
1585 +
1586 +namespace gfx {
1587 +
1588 +namespace {
1589 +#define evas_smart_preserve_window_type "Evas_Smart_Preserve_Window"
1590 +
1591 +const char PRESERVE_WINDOW_MOVE[] = "preserve,moved";
1592 +const char PRESERVE_WINDOW_RESIZE[] = "preserve,resized";
1593 +const char PRESERVE_WINDOW_REPAINT[] = "preserve,repainted";
1594 +const Evas_Smart_Cb_Description g_smart_callbacks[] = {
1595 +    {PRESERVE_WINDOW_MOVE, "(ii)"},
1596 +    {PRESERVE_WINDOW_RESIZE, "(ii)"},
1597 +    {PRESERVE_WINDOW_REPAINT, "(iiii)"},
1598 +    {NULL, NULL}};
1599 +
1600 +enum PreserveWindowSmartEventType {
1601 +  PreserveWindowMoveType,
1602 +  PreserveWindowResizeType,
1603 +  PreserveWindowRepaintType,
1604 +};
1605 +
1606 +const char* PreserveWindowSmartEvent(PreserveWindowSmartEventType type) {
1607 +  switch (type) {
1608 +    case PreserveWindowMoveType:
1609 +      return PRESERVE_WINDOW_MOVE;
1610 +      break;
1611 +    case PreserveWindowResizeType:
1612 +      return PRESERVE_WINDOW_RESIZE;
1613 +      break;
1614 +    case PreserveWindowRepaintType:
1615 +      return PRESERVE_WINDOW_REPAINT;
1616 +      break;
1617 +  }
1618 +  NOTREACHED();
1619 +  return "";
1620 +}
1621 +
1622 +struct PreserveWindowData {
1623 +  Evas_Object_Smart_Clipped_Data base;
1624 +  Evas_Object* window_;
1625 +  // FIXME (alexshalamov): It is dummy to receive input events.
1626 +  // We must find proper event handling way.
1627 +  Evas_Object* background_;
1628 +};
1629 +
1630 +bool IsPreserveWindowEvasObject(const Evas_Object* evas_object) {
1631 +    DCHECK(evas_object);
1632 +
1633 +    const char* evas_object_type = evas_object_type_get(evas_object);
1634 +    if (!evas_object_smart_type_check(evas_object,
1635 +                                      evas_smart_preserve_window_type)) {
1636 +      LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
1637 +        return false;
1638 +    }
1639 +
1640 +    const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
1641 +    if (!evas_smart) {
1642 +        LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
1643 +        return false;
1644 +    }
1645 +
1646 +    const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
1647 +    if (!smart_class) {
1648 +      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
1649 +        return false;
1650 +    }
1651 +
1652 +    return true;
1653 +}
1654 +
1655 +inline PreserveWindowData* ToSmartData(Evas_Object* evas_object) {
1656 +  DCHECK(evas_object);
1657 +  DCHECK(IsPreserveWindowEvasObject(evas_object));
1658 +  CHECK(evas_object_smart_data_get(evas_object));
1659 +  return static_cast<PreserveWindowData*>(evas_object_smart_data_get(evas_object));
1660 +}
1661 +
1662 +EVAS_SMART_SUBCLASS_NEW(evas_smart_preserve_window_type,
1663 +                        evas_smart_preserve_window,
1664 +                        Evas_Smart_Class,
1665 +                        Evas_Smart_Class,
1666 +                        evas_object_smart_clipped_class_get,
1667 +                        g_smart_callbacks);
1668 +
1669 +/* create and setup a new preserve window smart object's internals */
1670 +void evas_smart_preserve_window_smart_add(Evas_Object* o) {
1671 +  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
1672 +  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
1673 +  PreserveWindowData* smart_data;
1674 +  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
1675 +  if (!smart_data) {
1676 +    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
1677 +    if (!smart_data) {
1678 +      return;
1679 +    }
1680 +    evas_object_smart_data_set(o, smart_data);
1681 +  }
1682 +
1683 +  int x, y, w, h = 0;
1684 +  evas_object_geometry_get(o, &x, &y, &w, &h);
1685 +
1686 +  smart_data->window_ = elm_win_add(o, "preserve-window", ELM_WIN_DOCK);
1687 +  evas_object_resize(smart_data->window_, w, h);
1688 +  evas_object_show(smart_data->window_);
1689 +
1690 +  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
1691 +  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
1692 +  ecore_x_window_reparent(x_window, root_x_window, x, y);
1693 +
1694 +  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(smart_data->window_));
1695 +  evas_object_color_set(smart_data->background_, 0, 0, 0, 0);
1696 +  evas_object_size_hint_weight_set(smart_data->background_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1697 +  elm_win_resize_object_add(smart_data->window_, smart_data->background_);
1698 +  evas_object_focus_set(smart_data->background_, EINA_TRUE);
1699 +  evas_smart_preserve_window_parent_sc->add(o);
1700 +}
1701 +
1702 +void evas_smart_preserve_window_smart_del(Evas_Object* o) {
1703 +  PreserveWindowData* smart_data = ToSmartData(o);
1704 +  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
1705 +  ecore_x_window_reparent(x_window, 0 /* default root window */, 0 /* x */, 0 /* y */);
1706 +  evas_object_del(smart_data->background_);
1707 +  evas_object_del(smart_data->window_);
1708 +  evas_smart_preserve_window_parent_sc->del(o);
1709 +}
1710 +
1711 +void evas_smart_preserve_window_smart_show(Evas_Object* o) {
1712 +  PreserveWindowData* smart_data = ToSmartData(o);
1713 +  evas_object_show(smart_data->window_);
1714 +  evas_object_show(smart_data->background_);
1715 +  evas_smart_preserve_window_parent_sc->show(o);
1716 +}
1717 +
1718 +void evas_smart_preserve_window_smart_hide(Evas_Object* o) {
1719 +  PreserveWindowData* smart_data = ToSmartData(o);
1720 +  evas_object_hide(smart_data->window_);
1721 +  evas_object_hide(smart_data->background_);
1722 +  evas_smart_preserve_window_parent_sc->hide(o);
1723 +}
1724 +
1725 +void evas_smart_preserve_window_smart_move(Evas_Object* o,
1726 +                                           Evas_Coord x,
1727 +                                           Evas_Coord y) {
1728 +  Evas_Coord ox, oy;
1729 +  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
1730 +  if ((ox == x) && (oy == y))
1731 +    return;
1732 +
1733 +  PreserveWindowData* smart_data = ToSmartData(o);
1734 +  Ecore_X_Window x_window = elm_win_xwindow_get(smart_data->window_);
1735 +  Ecore_X_Window root_x_window = elm_win_xwindow_get(o);
1736 +  ecore_x_window_reparent(x_window, root_x_window, x, y);
1737 +
1738 +  int position[2] = {x, y};
1739 +  evas_object_smart_callback_call(
1740 +      o, PRESERVE_WINDOW_MOVE, static_cast<void*>(position));
1741 +
1742 +  /* this will trigger recalculation */
1743 +  evas_object_smart_changed(o);
1744 +}
1745 +
1746 +void evas_smart_preserve_window_smart_resize(Evas_Object* o,
1747 +                                             Evas_Coord w,
1748 +                                             Evas_Coord h) {
1749 +  Evas_Coord ow, oh;
1750 +  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
1751 +  if ((ow == w) && (oh == h))
1752 +    return;
1753 +
1754 +  PreserveWindowData* smart_data = ToSmartData(o);
1755 +  evas_object_resize(smart_data->window_, w, h);
1756 +
1757 +  int size[2] = {w, h};
1758 +  evas_object_smart_callback_call(
1759 +      o, PRESERVE_WINDOW_RESIZE, static_cast<void*>(size));
1760 +
1761 +  /* this will trigger recalculation */
1762 +  evas_object_smart_changed(o);
1763 +}
1764 +
1765 +/* act on child objects' properties, before rendering */
1766 +void evas_smart_preserve_window_smart_calculate(Evas_Object* o) {
1767 +  int dirty_rect[4] = { 0, };
1768 +  // FIXME: how to know dirty rect actually.
1769 +  evas_object_geometry_get(o, &dirty_rect[0], &dirty_rect[1], &dirty_rect[2], &dirty_rect[3]);
1770 +  evas_object_smart_callback_call(
1771 +      o, PRESERVE_WINDOW_REPAINT, static_cast<void*>(dirty_rect));
1772 +}
1773 +
1774 +/* setting our smart interface */
1775 +void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
1776 +  /* specializing these two */
1777 +  sc->add = evas_smart_preserve_window_smart_add;
1778 +  sc->del = evas_smart_preserve_window_smart_del;
1779 +  sc->show = evas_smart_preserve_window_smart_show;
1780 +  sc->hide = evas_smart_preserve_window_smart_hide;
1781 +
1782 +  /* clipped smart object has no hook on move, resize and calculation */
1783 +  sc->move = evas_smart_preserve_window_smart_move;
1784 +  sc->resize = evas_smart_preserve_window_smart_resize;
1785 +  sc->calculate = evas_smart_preserve_window_smart_calculate;
1786 +}
1787 +
1788 +// SmartObjectEventHandler implementation.
1789 +template <Evas_Callback_Type EventType> class SmartObjectEventHandler {
1790 + public:
1791 +  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
1792 +    evas_object_event_callback_add(evas_object, EventType, HandleEvent, delegate);
1793 +  }
1794 +
1795 +  static void Unsubscribe(Evas_Object* evas_object) {
1796 +    evas_object_event_callback_del(evas_object, EventType, HandleEvent);
1797 +  }
1798 +
1799 +  static void HandleEvent(void* data, Evas*, Evas_Object*, void* event_info);
1800 +};
1801 +
1802 +template <>
1803 +void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::HandleEvent(
1804 +    void* data, Evas*, Evas_Object*, void* event_info) {
1805 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1806 +  delegate->PreserveWindowMouseDown(static_cast<Evas_Event_Mouse_Down*>(event_info));
1807 +}
1808 +
1809 +template <>
1810 +void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::HandleEvent(
1811 +    void* data, Evas*, Evas_Object*, void* event_info) {
1812 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1813 +  delegate->PreserveWindowMouseUp(static_cast<Evas_Event_Mouse_Up*>(event_info));
1814 +}
1815 +
1816 +template <>
1817 +void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::HandleEvent(
1818 +    void* data, Evas*, Evas_Object*, void* event_info) {
1819 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1820 +  delegate->PreserveWindowMouseMove(static_cast<Evas_Event_Mouse_Move*>(event_info));
1821 +}
1822 +
1823 +template <>
1824 +void SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::HandleEvent(
1825 +    void* data, Evas*, Evas_Object*, void* event_info) {
1826 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1827 +  delegate->PreserveWindowMouseWheel(static_cast<Evas_Event_Mouse_Wheel*>(event_info));
1828 +}
1829 +
1830 +template <>
1831 +void SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::HandleEvent(
1832 +    void* data, Evas*, Evas_Object*, void* event_info) {
1833 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1834 +  delegate->PreserveWindowKeyDown(static_cast<Evas_Event_Key_Down*>(event_info));
1835 +}
1836 +
1837 +template <>
1838 +void SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::HandleEvent(
1839 +    void* data, Evas*, Evas_Object*, void* event_info) {
1840 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1841 +  delegate->PreserveWindowKeyUp(static_cast<Evas_Event_Key_Up*>(event_info));
1842 +}
1843 +
1844 +template <>
1845 +void SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::HandleEvent(
1846 +    void* data, Evas*, Evas_Object*, void*) {
1847 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1848 +  delegate->PreserveWindowFocusIn();
1849 +}
1850 +
1851 +template <>
1852 +void SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::HandleEvent(
1853 +    void* data, Evas*, Evas_Object*, void*) {
1854 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1855 +  delegate->PreserveWindowFocusOut();
1856 +}
1857 +
1858 +template <>
1859 +void SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::HandleEvent(
1860 +    void* data, Evas*, Evas_Object*, void*) {
1861 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1862 +  delegate->PreserveWindowShow();
1863 +}
1864 +
1865 +template <>
1866 +void SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::HandleEvent(
1867 +    void* data, Evas*, Evas_Object*, void*) {
1868 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1869 +  delegate->PreserveWindowHide();
1870 +}
1871 +
1872 +// SmartObjectSmartHandler implementation.
1873 +template <PreserveWindowSmartEventType EventType> class SmartObjectSmartHandler {
1874 + public:
1875 +  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
1876 +    evas_object_smart_callback_add(evas_object,
1877 +                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
1878 +                                   HandleEventMove, delegate);
1879 +    evas_object_smart_callback_add(evas_object,
1880 +                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
1881 +                                   HandleEventResize, delegate);
1882 +    evas_object_smart_callback_add(evas_object,
1883 +                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
1884 +                                   HandleEventRepaint, delegate);
1885 +  }
1886 +
1887 +  static void Unsubscribe(Evas_Object* evas_object) {
1888 +    evas_object_smart_callback_del(evas_object,
1889 +                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
1890 +                                   HandleEventMove);
1891 +    evas_object_smart_callback_del(evas_object,
1892 +                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
1893 +                                   HandleEventResize);
1894 +    evas_object_smart_callback_del(evas_object,
1895 +                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
1896 +                                   HandleEventRepaint);
1897 +  }
1898 +
1899 +  static void HandleEventMove(void* data, Evas_Object*, void* event_info);
1900 +  static void HandleEventResize(void* data, Evas_Object*, void* event_info);
1901 +  static void HandleEventRepaint(void* data, Evas_Object*, void* event_info);
1902 +};
1903 +
1904 +template <PreserveWindowSmartEventType EventType>
1905 +void SmartObjectSmartHandler<EventType>::HandleEventMove(
1906 +    void* data, Evas_Object*, void* event_info) {
1907 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1908 +  int* position = static_cast<int*>(event_info);
1909 +  delegate->PreserveWindowMove(gfx::Point(position[0], position[1]));
1910 +}
1911 +
1912 +template <PreserveWindowSmartEventType EventType>
1913 +void SmartObjectSmartHandler<EventType>::HandleEventResize(
1914 +    void* data, Evas_Object*, void* event_info) {
1915 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1916 +  int* size = static_cast<int*>(event_info);
1917 +  delegate->PreserveWindowResize(gfx::Size(size[0], size[1]));
1918 +}
1919 +
1920 +template <PreserveWindowSmartEventType EventType>
1921 +void SmartObjectSmartHandler<EventType>::HandleEventRepaint(
1922 +    void* data, Evas_Object*, void* event_info) {
1923 +  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
1924 +  int* dirty_rect = static_cast<int*>(event_info);
1925 +  delegate->PreserveWindowRepaint(gfx::Rect(dirty_rect[0],
1926 +                                            dirty_rect[1],
1927 +                                            dirty_rect[2],
1928 +                                            dirty_rect[3]));
1929 +}
1930 +
1931 +}  // namespace
1932 +
1933 +// static
1934 +PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
1935 +                                       Evas* evas) {
1936 +  return new PreserveWindow(delegate, evas);
1937 +}
1938 +
1939 +PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
1940 +    : delegate_(delegate) {
1941 +  smart_object_ = evas_object_smart_add(evas, evas_smart_preserve_window_smart_class_new());
1942 +  evas_object_show(smart_object_);
1943 +
1944 +  SmartObjectSmartHandler<PreserveWindowMoveType>::Subscribe(smart_object_, delegate_);
1945 +  SmartObjectSmartHandler<PreserveWindowResizeType>::Subscribe(smart_object_, delegate_);
1946 +  SmartObjectSmartHandler<PreserveWindowRepaintType>::Subscribe(smart_object_, delegate_);
1947 +
1948 +  PreserveWindowData* smart_data = ToSmartData(smart_object_);
1949 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background_, delegate_);
1950 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background_, delegate_);
1951 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background_, delegate_);
1952 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background_, delegate_);
1953 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background_, delegate_);
1954 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background_, delegate_);
1955 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background_, delegate_);
1956 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background_, delegate_);
1957 +  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background_, delegate_);
1958 +  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background_, delegate_);
1959 +
1960 +  // FIXME: After creation, request redraw.
1961 +  evas_object_smart_changed(smart_object_);
1962 +}
1963 +
1964 +PreserveWindow::~PreserveWindow() {
1965 +  SmartObjectSmartHandler<PreserveWindowMoveType>::Unsubscribe(smart_object_);
1966 +  SmartObjectSmartHandler<PreserveWindowResizeType>::Unsubscribe(smart_object_);
1967 +  SmartObjectSmartHandler<PreserveWindowRepaintType>::Unsubscribe(smart_object_);
1968 +
1969 +  PreserveWindowData* smart_data = ToSmartData(smart_object_);
1970 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Unsubscribe(smart_data->background_);
1971 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Unsubscribe(smart_data->background_);
1972 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Unsubscribe(smart_data->background_);
1973 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Unsubscribe(smart_data->background_);
1974 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Unsubscribe(smart_data->background_);
1975 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Unsubscribe(smart_data->background_);
1976 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Unsubscribe(smart_data->background_);
1977 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Unsubscribe(smart_data->background_);
1978 +  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Unsubscribe(smart_data->background_);
1979 +  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Unsubscribe(smart_data->background_);
1980 +
1981 +  evas_object_del(smart_object_);
1982 +}
1983 +
1984 +
1985 +Evas_Object* PreserveWindow::EvasWindow() {
1986 +  PreserveWindowData* smart_data = ToSmartData(smart_object_);
1987 +  return smart_data->window_;
1988 +}
1989 +
1990 +}  // namespace gfx
1991 diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
1992 new file mode 100644
1993 index 0000000..56a0b78
1994 --- /dev/null
1995 +++ b/ui/gfx/preserve_window_efl.h
1996 @@ -0,0 +1,37 @@
1997 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
1998 +// Use of this source code is governed by a BSD-style license that can be
1999 +// found in the LICENSE file.
2000 +
2001 +#ifndef UI_GFX_PRESERVE_WINDOW_EFL_H_
2002 +#define UI_GFX_PRESERVE_WINDOW_EFL_H_
2003 +
2004 +#include <Evas.h>
2005 +
2006 +#include "base/basictypes.h"
2007 +#include "base/memory/scoped_ptr.h"
2008 +#include "ui/base/ui_export.h"
2009 +#include "ui/gfx/preserve_window_delegate_efl.h"
2010 +
2011 +namespace gfx {
2012 +
2013 +class UI_EXPORT PreserveWindow {
2014 + public:
2015 +  static PreserveWindow* Create(PreserveWindowDelegate*, Evas*);
2016 +
2017 +  ~PreserveWindow();
2018 +
2019 +  Evas_Object* SmartObject() const { return smart_object_; }
2020 +  Evas_Object* EvasWindow();
2021 +
2022 + private:
2023 +  PreserveWindow(PreserveWindowDelegate*, Evas*);
2024 +
2025 +  PreserveWindowDelegate* delegate_;
2026 +  Evas_Object* smart_object_;
2027 +
2028 +  DISALLOW_COPY_AND_ASSIGN(PreserveWindow);
2029 +};
2030 +
2031 +}  // namespace gfx
2032 +
2033 +#endif  // UI_GFX_PRESERVE_WINDOW_EFL_H_
2034 diff --git a/ui/gfx/screen_efl.cc b/ui/gfx/screen_efl.cc
2035 new file mode 100644
2036 index 0000000..8bf4f16
2037 --- /dev/null
2038 +++ b/ui/gfx/screen_efl.cc
2039 @@ -0,0 +1,87 @@
2040 +// Copyright (c) 2013 Intel Corporation. All rights reserved.
2041 +// Use of this source code is governed by a BSD-style license that can be
2042 +// found in the LICENSE file.
2043 +
2044 +#include "ui/gfx/screen.h"
2045 +
2046 +#include <Ecore_X.h>
2047 +#include <Ecore_Evas.h>
2048 +
2049 +#include "base/logging.h"
2050 +#include "ui/gfx/display.h"
2051 +
2052 +namespace {
2053 +
2054 +class ScreenEfl : public gfx::Screen {
2055 + public:
2056 +  ScreenEfl() {
2057 +  }
2058 +
2059 +  virtual ~ScreenEfl() {
2060 +  }
2061 +
2062 +  virtual bool IsDIPEnabled() OVERRIDE {
2063 +    return false;
2064 +  }
2065 +
2066 +  virtual gfx::Point GetCursorScreenPoint() OVERRIDE {
2067 +    return gfx::Point();
2068 +  }
2069 +
2070 +  virtual gfx::NativeWindow GetWindowAtCursorScreenPoint() OVERRIDE {
2071 +    NOTIMPLEMENTED();
2072 +    return NULL;
2073 +  }
2074 +
2075 +  virtual int GetNumDisplays() OVERRIDE {
2076 +    return ecore_x_screen_count_get();
2077 +  }
2078 +
2079 +  virtual gfx::Display GetDisplayNearestWindow(
2080 +      gfx::NativeView view) const OVERRIDE {
2081 +    return GetPrimaryDisplay();
2082 +  }
2083 +
2084 +  virtual gfx::Display GetDisplayNearestPoint(
2085 +      const gfx::Point& point) const OVERRIDE {
2086 +    return GetPrimaryDisplay();
2087 +  }
2088 +
2089 +  virtual gfx::Display GetDisplayMatching(
2090 +      const gfx::Rect& match_rect) const OVERRIDE {
2091 +    return GetPrimaryDisplay();
2092 +  }
2093 +
2094 +  virtual gfx::Display GetPrimaryDisplay() const OVERRIDE {
2095 +    static bool initialized = false;
2096 +    if (!initialized) {
2097 +      ecore_x_init(NULL);
2098 +      initialized = true;
2099 +    }
2100 +
2101 +    int width = 0, height = 0;
2102 +    Ecore_X_Screen* screen = ecore_x_default_screen_get();
2103 +    ecore_x_screen_size_get(screen, &width, &height);
2104 +    // fprintf(stdout, "%dx%d\n", width, height);
2105 +    return gfx::Display(0, gfx::Rect(width, height));
2106 +  }
2107 +
2108 +  virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE {
2109 +  }
2110 +
2111 +  virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE {
2112 +  }
2113 +
2114 + private:
2115 +  DISALLOW_COPY_AND_ASSIGN(ScreenEfl);
2116 +};
2117 +
2118 +}  // namespace
2119 +
2120 +namespace gfx {
2121 +
2122 +Screen* CreateNativeScreen() {
2123 +  return new ScreenEfl;
2124 +}
2125 +
2126 +} // namespace gfx
2127 diff --git a/ui/ui.gyp b/ui/ui.gyp
2128 index 797fd78..a7c9cbf 100644
2129 --- a/ui/ui.gyp
2130 +++ b/ui/ui.gyp
2131 @@ -478,6 +478,9 @@
2132          'gfx/point_conversions.h',
2133          'gfx/point_f.cc',
2134          'gfx/point_f.h',
2135 +        'gfx/preserve_window_efl.cc',
2136 +        'gfx/preserve_window_efl.h',
2137 +        'gfx/preserve_window_delegate_efl.h',
2138          'gfx/quad_f.cc',
2139          'gfx/quad_f.h',
2140          'gfx/rect.cc',
2141 @@ -698,8 +701,14 @@
2142              '../build/linux/system.gyp:efl',
2143            ],
2144            'sources': [
2145 +            'base/clipboard/clipboard_efl.cc',
2146 +            'base/resource/resource_bundle_efl.cc',
2147              'gfx/efl_util.cc',
2148              'gfx/efl_util.h',
2149 +            'gfx/screen_efl.cc',
2150 +          ],
2151 +          'sources!': [
2152 +            'gfx/screen_gtk.cc',
2153            ],
2154          }],
2155          ['chromeos==1 or (use_aura==1 and OS=="linux" and use_x11==0)', {
2156 -- 
2157 1.8.1.2
2158