[M69 Dev][Tizen] Enable touch events for mobile/wearable profile
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / content / browser / renderer_host / render_widget_host_view_efl.cc
1 // Copyright 2014-2015 Samsung Electronics. All rights reserved.
2 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "content/browser/renderer_host/render_widget_host_view_efl.h"
7
8 #include <Ecore.h>
9 #include <Ecore_Evas.h>
10 #include <Ecore_Input.h>
11 #include <Elementary.h>
12 #include "ecore_x_wayland_wrapper.h"
13
14 #include "base/auto_reset.h"
15 #include "base/bind.h"
16 #include "base/callback_helpers.h"
17 #include "base/command_line.h"
18 #include "base/logging.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/message_loop/message_loop.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/trace_event/trace_event.h"
25 #include "content/browser/renderer_host/disambiguation_popup_efl.h"
26 #include "content/browser/renderer_host/edge_effect.h"
27 #include "content/browser/renderer_host/event_with_latency_info.h"
28 #include "content/browser/renderer_host/im_context_efl.h"
29 #include "content/browser/renderer_host/render_view_host_impl.h"
30 #include "content/browser/renderer_host/render_widget_host_impl.h"
31 #include "content/browser/renderer_host/ui_events_helper.h"
32 #include "content/browser/renderer_host/web_event_factory_efl.h"
33 #include "content/common/cursors/webcursor_efl.h"
34 #include "content/common/input_messages.h"
35 #include "content/common/view_messages.h"
36 #include "content/public/browser/browser_thread.h"
37 #include "content/public/browser/context_factory.h"
38 #include "content/public/browser/render_process_host.h"
39 #include "content/public/browser/web_contents_delegate.h"
40 #include "content/public/common/content_switches.h"
41 #include "gpu/command_buffer/service/mailbox_manager.h"
42 #include "gpu/ipc/common/gpu_messages.h"
43 #include "media/base/video_frame.h"
44 #include "media/base/video_util.h"
45 #include "skia/ext/image_operations.h"
46 #include "third_party/blink/public/platform/web_input_event.h"
47 #include "third_party/blink/public/platform/web_screen_info.h"
48 #include "third_party/blink/public/platform/web_touch_point.h"
49 #include "tizen/system_info.h"
50 #include "ui/base/clipboard/clipboard_helper_efl.h"
51 #include "ui/base/layout.h"
52 #include "ui/events/blink/blink_event_util.h"
53 #include "ui/events/blink/did_overscroll_params.h"
54 #include "ui/events/event_switches.h"
55 #include "ui/events/event_utils.h"
56 #define private public
57 #include "ui/events/gestures/gesture_provider_aura.h"
58 #undef private
59 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
60 #include "ui/display/device_display_info_efl.h"
61 #include "ui/display/display.h"
62 #include "ui/display/screen.h"
63 #include "ui/events/gestures/gesture_recognizer_impl_efl.h"
64 #include "ui/gfx/geometry/dip_util.h"
65 #include "ui/gfx/geometry/rect.h"
66 #include "ui/gfx/selection_bound.h"
67 #include "ui/gl/gl_shared_context_efl.h"
68
69 #if defined(OS_TIZEN)
70 #include <efl_extension.h>
71 #endif
72
73 #define EFL_MAX_WIDTH 10000
74 #define EFL_MAX_HEIGHT 10000  // borrowed from GTK+ port
75
76 #define MAX_SURFACE_WIDTH_EGL 4096   // max supported Framebuffer width
77 #define MAX_SURFACE_HEIGHT_EGL 4096  // max supported Framebuffer height
78
79 // These two constants are redefinitions of the original constants defined
80 // in evas_common.c. These are not supposed to be used directly by apps,
81 // but we do this because of chromium uses fbo for direct rendering.
82 #define EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE (1 << 12)
83 #define EVAS_GL_OPTIONS_DIRECT_OVERRIDE (1 << 13)
84
85 namespace content {
86
87 namespace {
88
89 bool IsShiftKey(const char* key) {
90   if (!key)
91     return false;
92   return !strcmp(key, "Shift_L") || !strcmp(key, "Shift_R");
93 }
94
95 // Creates a WebGestureEvent from a ui::GestureEvent. Note that it does not
96 // populate the event coordinates (i.e. |x|, |y|, |globalX|, and |globalY|). So
97 // the caller must populate these fields.
98 blink::WebGestureEvent MakeWebGestureEventFromUIEvent(
99     const ui::GestureEvent& event) {
100   return ui::CreateWebGestureEvent(
101       event.details(), event.time_stamp(), event.location_f(),
102       event.root_location_f(), event.flags(), event.unique_touch_event_id());
103 }
104
105 }  // namespace
106
107 class ScreenshotCapturedCallback {
108  public:
109   ScreenshotCapturedCallback(Screenshot_Captured_Callback func, void* user_data)
110       : func_(func), user_data_(user_data) {}
111   void Run(Evas_Object* image) {
112     if (func_ != NULL)
113       (func_)(image, user_data_);
114   }
115
116  private:
117   Screenshot_Captured_Callback func_;
118   void* user_data_;
119 };
120
121 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
122 // FIXME: EWK_BRINGUP definition should be removed.
123 // GetDefaultScreenInfo was removed in
124 // content/browser/renderer_host/render_widget_host_view_base.h
125 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
126     blink::WebScreenInfo* results) {
127   const display::Display display =
128       display::Screen::GetScreen()->GetPrimaryDisplay();
129
130   results->rect = display.bounds();
131   results->availableRect = display.work_area();
132   results->deviceScaleFactor = display.device_scale_factor();
133   results->orientationAngle = display.RotationAsDegree();
134
135   if (IsMobileProfile() || IsWearableProfile())
136     results->orientationType =
137         RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
138   else
139     results->orientationType =
140         RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display);
141
142   // TODO(derat|oshima): Don't hardcode this. Get this from display object.
143   results->depth = 24;
144   results->depthPerComponent = 8;
145 }
146 #endif  // !defined(EWK_BRINGUP)
147
148 RenderWidgetHostViewEfl::RenderWidgetHostViewEfl(RenderWidgetHost* widget_host,
149                                                  WebContents& web_contents)
150     : RenderWidgetHostViewBase(widget_host),
151       evasgl_delegated_frame_host_(new EvasGLDelegatedFrameHost(this)),
152       im_context_(NULL),
153       evas_(NULL),
154       parent_view_(NULL),
155       smart_parent_(NULL),
156       content_image_(NULL),
157       content_image_elm_host_(NULL),
158       evas_gl_initialized_(false),
159       device_scale_factor_(1.0f),
160       magnifier_(false),
161       is_loading_(false),
162       gesture_recognizer_(ui::GestureRecognizer::Create()),
163       current_orientation_(0),
164       evas_gl_(NULL),
165       evas_gl_api_(NULL),
166       evas_gl_config_(NULL),
167       evas_gl_context_(NULL),
168       evas_gl_surface_(NULL),
169       handling_disambiguation_popup_gesture_(false),
170       touch_events_enabled_(false),
171       web_contents_(web_contents),
172       weak_factory_(this) {
173   parent_view_ = static_cast<Evas_Object*>(web_contents.GetNativeView());
174   evas_ = evas_object_evas_get(parent_view_);
175
176   InitializeDeviceDisplayInfo();
177
178   SetDoubleTapSupportEnabled(touch_events_enabled_);
179
180   device_scale_factor_ =
181       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
182
183   host_->SetView(this);
184
185   static bool scale_factor_initialized = false;
186   if (!scale_factor_initialized) {
187     std::vector<ui::ScaleFactor> supported_scale_factors;
188     supported_scale_factors.push_back(ui::SCALE_FACTOR_100P);
189     supported_scale_factors.push_back(ui::SCALE_FACTOR_200P);
190     ui::SetSupportedScaleFactors(supported_scale_factors);
191     scale_factor_initialized = true;
192   }
193
194   gesture_recognizer_->AddGestureEventHelper(this);
195 }
196
197 void RenderWidgetHostViewEfl::InitAsChild(gfx::NativeView /* parent_view */) {
198   content_image_elm_host_ = elm_bg_add(parent_view_);
199   content_image_ = evas_object_image_filled_add(evas_);
200   elm_object_part_content_set(content_image_elm_host_, "overlay",
201                               content_image_);
202   elm_object_focus_allow_set(content_image_elm_host_, EINA_TRUE);
203
204   Evas_Object* smart_parent = evas_object_smart_parent_get(parent_view_);
205   if (smart_parent) {
206     // If our parent is a member of some smart object we also want
207     // to join that group.
208     smart_parent_ = smart_parent;
209     evas_object_smart_member_add(content_image_elm_host_, smart_parent);
210   }
211
212   int x, y, width = 0, height = 0;
213   evas_object_geometry_get(parent_view_, &x, &y, &width, &height);
214   if (width == 0 || height == 0)
215     width = height = 1;
216   evas_object_image_size_set(content_image_, width, height);
217   evas_object_geometry_set(content_image_elm_host_, x, y, width, height);
218
219   evas_object_event_callback_add(parent_view_, EVAS_CALLBACK_RESIZE,
220                                  OnParentViewResize, this);
221   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_IN,
222                                  OnFocusIn, this);
223   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_OUT,
224                                  OnFocusOut, this);
225   evas_object_smart_callback_add(content_image_elm_host_, "focused",
226                                  OnHostFocusIn, this);
227   evas_object_smart_callback_add(content_image_elm_host_, "unfocused",
228                                  OnHostFocusOut, this);
229
230   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
231                                  OnMouseDown, this);
232   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_UP,
233                                  OnMouseUp, this);
234   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
235                                  OnMouseMove, this);
236   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
237                                  OnMouseWheel, this);
238   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_DOWN,
239                                  OnKeyDown, this);
240   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_UP, OnKeyUp,
241                                  this);
242
243   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_DOWN,
244                                  OnMultiTouchDownEvent, this);
245   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_MOVE,
246                                  OnMultiTouchMoveEvent, this);
247   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_UP,
248                                  OnMultiTouchUpEvent, this);
249
250 #if defined(OS_TIZEN)
251   if (IsMobileProfile() || IsWearableProfile()) {
252     eext_object_event_callback_add(content_image_, EEXT_CALLBACK_BACK,
253                                    OnHWBackEvent, this);
254   }
255 #endif
256
257   // IMContext calls evas() getter on 'this' so it needs to be
258   // initialized after evas_ is valid
259   im_context_ = IMContextEfl::Create(this);
260   Init_EvasGL(width, height);
261 }
262
263 #if defined(NDEBUG)
264 #define GL_CHECK_HELPER(code, msg) ((code), false)
265 #else
266 static GLenum g_gl_err;
267 #define GL_CHECK_HELPER(code, msg)                                          \
268   (((void)(code), ((g_gl_err = evas_gl_api_->glGetError()) == GL_NO_ERROR)) \
269        ? false                                                              \
270        : ((LOG(ERROR) << "GL Error: " << g_gl_err << "    " << msg), true))
271 #endif
272
273 #define GL_CHECK(code) GL_CHECK_HELPER(code, "")
274 #define GL_CHECK_STATUS(msg) GL_CHECK_HELPER(1, msg)
275
276 RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
277   MakeCurrent();
278   evasgl_delegated_frame_host_.reset();
279   ClearCurrent();
280
281   if (im_context_)
282     delete im_context_;
283
284   evas_object_event_callback_del_full(parent_view_, EVAS_CALLBACK_RESIZE,
285                                       OnParentViewResize, this);
286   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_IN,
287                                  OnFocusIn);
288   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_OUT,
289                                  OnFocusOut);
290   evas_object_smart_callback_del(content_image_elm_host_, "focused",
291                                  OnHostFocusIn);
292   evas_object_smart_callback_del(content_image_elm_host_, "unfocused",
293                                  OnHostFocusOut);
294
295   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
296                                  OnMouseDown);
297   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_UP,
298                                  OnMouseUp);
299   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
300                                  OnMouseMove);
301   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
302                                  OnMouseWheel);
303   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_DOWN,
304                                  OnKeyDown);
305   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_UP, OnKeyUp);
306
307   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_DOWN,
308                                  OnMultiTouchDownEvent);
309   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_MOVE,
310                                  OnMultiTouchMoveEvent);
311   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_UP,
312                                  OnMultiTouchUpEvent);
313
314   evas_object_del(content_image_elm_host_);
315   content_image_elm_host_ = NULL;
316   content_image_ = NULL;
317   parent_view_ = NULL;
318 }
319
320 gfx::Point RenderWidgetHostViewEfl::ConvertPointInViewPix(gfx::Point point) {
321   return gfx::ToFlooredPoint(
322       gfx::ScalePoint(gfx::PointF(point), device_scale_factor_));
323 }
324
325 gfx::Rect RenderWidgetHostViewEfl::GetViewBoundsInPix() const {
326   int x, y, w, h;
327   evas_object_geometry_get(content_image_elm_host_, &x, &y, &w, &h);
328   return gfx::Rect(x, y, w, h);
329 }
330
331 bool RenderWidgetHostViewEfl::ClearCurrent() {
332   return evas_gl_make_current(evas_gl_, 0, 0);
333 }
334
335 bool RenderWidgetHostViewEfl::MakeCurrent() {
336   return evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
337 }
338
339 void RenderWidgetHostViewEfl::UpdateRotationDegrees(int rotation_degrees) {
340   display::DeviceDisplayInfoEfl display_info;
341   display_info.SetRotationDegrees(rotation_degrees);
342 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
343   Send(new ViewMsg_UpdateRotationDegrees(host_->GetRoutingID(),
344                                          display_info.GetRotationDegrees()));
345 #endif
346 }
347
348 Evas_GL_API* RenderWidgetHostViewEfl::GetEvasGLAPI() {
349   return evas_gl_api_;
350 }
351
352 Evas_GL* RenderWidgetHostViewEfl::GetEvasGL() {
353   return evas_gl_;
354 }
355
356 void RenderWidgetHostViewEfl::DelegatedFrameHostSendReclaimCompositorResources(
357     const viz::LocalSurfaceId& local_surface_id,
358     const std::vector<viz::ReturnedResource>& resources) {
359   renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(resources);
360 }
361
362 void RenderWidgetHostViewEfl::InitializeDeviceDisplayInfo() {
363   static bool initialized = false;
364   if (initialized)
365     return;
366
367   initialized = true;
368
369   int display_width = 0, display_height = 0, dpi = 0;
370   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
371   ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &display_width,
372                                  &display_height);
373   ecore_evas_screen_dpi_get(ee, &dpi, nullptr);
374
375   display::DeviceDisplayInfoEfl display_info;
376   display_info.Update(display_width, display_height,
377                       display_info.ComputeDIPScale(dpi),
378                       ecore_evas_rotation_get(ee));
379 }
380
381 void RenderWidgetHostViewEfl::Invalidate(bool immediate) {
382   if (immediate)
383     evas_render(evas_);
384   else
385     evas_object_image_pixels_dirty_set(content_image_, true);
386 }
387
388 void RenderWidgetHostViewEfl::SwapBrowserFrame(
389     const viz::LocalSurfaceId& local_surface_id,
390     viz::CompositorFrame frame) {
391   // Swap frame using evasgl delegated frame host.
392   DCHECK(evasgl_delegated_frame_host_);
393   evasgl_delegated_frame_host_->SwapDelegatedFrame(local_surface_id,
394                                                    std::move(frame));
395   web_contents_.GetDelegate()->DidRenderFrame();
396   Invalidate(false);
397 }
398
399 void RenderWidgetHostViewEfl::ClearBrowserFrame() {
400   DCHECK(evas_gl_api_);
401   GL_CHECK(evas_gl_api_->glClearColor(1.0, 1.0, 1.0, 1.0));
402   GL_CHECK(evas_gl_api_->glClear(GL_COLOR_BUFFER_BIT));
403 }
404
405 void RenderWidgetHostViewEfl::RenderBrowserFrame() {
406   if (!MakeCurrent()) {
407     LOG(ERROR) << "RenderWidgetHostViewEfl::MakeCurrent() failed. Frame"
408                << "cannot be rendered.";
409     return;
410   }
411
412   // TODO(prashant.n): Check if frame can be cleared only when frame_host
413   // does not render anything.
414   ClearBrowserFrame();
415
416   // Render frame using evasgl delegated frame host.
417   DCHECK(evasgl_delegated_frame_host_);
418   evasgl_delegated_frame_host_->RenderDelegatedFrame(GetViewBoundsInPix());
419
420   ClearCurrent();
421 }
422
423 void RenderWidgetHostViewEfl::EvasObjectImagePixelsGetCallback(
424     void* data,
425     Evas_Object* obj) {
426   RenderWidgetHostViewEfl* rwhv_efl =
427       reinterpret_cast<RenderWidgetHostViewEfl*>(data);
428   rwhv_efl->RenderBrowserFrame();
429 }
430
431 void RenderWidgetHostViewEfl::Init_EvasGL(int width, int height) {
432   CHECK(width > 0 && height > 0);
433
434   evas_gl_config_ = evas_gl_config_new();
435   evas_gl_config_->options_bits = (Evas_GL_Options_Bits)(
436       EVAS_GL_OPTIONS_DIRECT | EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE |
437       EVAS_GL_OPTIONS_DIRECT_OVERRIDE);
438   evas_gl_config_->color_format = EVAS_GL_RGBA_8888;
439   evas_gl_config_->depth_bits = EVAS_GL_DEPTH_BIT_24;
440   evas_gl_config_->stencil_bits = EVAS_GL_STENCIL_BIT_8;
441
442   evas_gl_ = evas_gl_new(evas_);
443   evas_gl_api_ = evas_gl_api_get(evas_gl_);
444   evas_gl_context_ =
445       evas_gl_context_create(evas_gl_, GLSharedContextEfl::GetEvasGLContext());
446   if (!evas_gl_context_)
447     LOG(FATAL) << "Failed to create evas gl context";
448
449   if (width > MAX_SURFACE_WIDTH_EGL)
450     width = MAX_SURFACE_WIDTH_EGL;
451
452   if (height > MAX_SURFACE_HEIGHT_EGL)
453     height = MAX_SURFACE_HEIGHT_EGL;
454
455   CreateNativeSurface(width, height);
456
457   MakeCurrent();
458   ClearBrowserFrame();
459   evasgl_delegated_frame_host_->Initialize();
460   ClearCurrent();
461
462   evas_gl_initialized_ = true;
463 }
464
465 void RenderWidgetHostViewEfl::CreateNativeSurface(int width, int height) {
466   if (width == 0 || height == 0) {
467     LOG(WARNING) << "Invalid surface size: " << width << "x" << height;
468     return;
469   }
470
471   if (evas_gl_surface_) {
472     evas_object_image_native_surface_set(content_image_, NULL);
473     evas_gl_surface_destroy(evas_gl_, evas_gl_surface_);
474     ClearCurrent();
475   }
476
477   evas_gl_surface_ =
478       evas_gl_surface_create(evas_gl_, evas_gl_config_, width, height);
479   if (!evas_gl_surface_)
480     LOG(FATAL) << "Failed to create evas gl surface";
481
482   Evas_Native_Surface nativeSurface;
483   if (evas_gl_native_surface_get(evas_gl_, evas_gl_surface_, &nativeSurface)) {
484     evas_object_image_native_surface_set(content_image_, &nativeSurface);
485     evas_object_image_pixels_get_callback_set(
486         content_image_, EvasObjectImagePixelsGetCallback, this);
487     evas_object_image_pixels_dirty_set(content_image_, true);
488   } else {
489     LOG(FATAL) << "Failed to get native surface";
490   }
491 }
492
493 void RenderWidgetHostViewEfl::SetEvasHandler(
494     scoped_refptr<EvasEventHandler> evas_event_handler) {
495   evas_event_handler_ = evas_event_handler;
496 }
497
498 bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
499   bool handled = true;
500   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewEfl, message)
501 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
502     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputInFormStateChanged,
503                         OnTextInputInFormStateChanged)
504     IPC_MESSAGE_HANDLER(ViewHostMsg_SnapshotDataReceived,
505                         OnSnapshotDataReceived)
506 #endif
507     IPC_MESSAGE_UNHANDLED(handled = false)
508   IPC_END_MESSAGE_MAP()
509   return handled;
510 }
511
512 bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
513   return host_->Send(message);
514 }
515
516 void RenderWidgetHostViewEfl::OnSnapshotDataReceived(SkBitmap bitmap,
517                                                      int snapshotId) {
518   Evas_Object* image = NULL;
519   if (!bitmap.empty()) {
520     image = evas_object_image_filled_add(evas_);
521     evas_object_image_size_set(image, bitmap.width(), bitmap.height());
522     evas_object_image_data_copy_set(image, bitmap.getPixels());
523   }
524
525   ScreenshotCapturedCallback* callback =
526       screen_capture_cb_map_.Lookup(snapshotId);
527   if (!callback) {
528     return;
529   }
530   callback->Run(image);
531   screen_capture_cb_map_.Remove(snapshotId);
532 }
533
534 void RenderWidgetHostViewEfl::InitAsPopup(RenderWidgetHostView*,
535                                           const gfx::Rect&) {
536   NOTIMPLEMENTED();
537 }
538
539 void RenderWidgetHostViewEfl::InitAsFullscreen(RenderWidgetHostView*) {
540   NOTIMPLEMENTED();
541 }
542
543 #if defined(USE_WAYLAND)
544 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
545 Ecore_Wl2_Window* RenderWidgetHostViewEfl::GetEcoreWlWindow() const {
546   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
547   return ecore_evas_wayland2_window_get(ee);
548 }
549 #else
550 Ecore_Wl_Window* RenderWidgetHostViewEfl::GetEcoreWlWindow() const {
551   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
552   return ecore_evas_wayland_window_get(ee);
553 }
554 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
555 #else
556 Ecore_X_Window RenderWidgetHostViewEfl::GetEcoreXWindow() const {
557   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
558   return ecore_evas_gl_x11_window_get(ee);
559 }
560 #endif  // USE_WAYLAND
561
562 void RenderWidgetHostViewEfl::SetSize(const gfx::Size& size) {
563   // This is a hack. See WebContentsView::SizeContents
564   int width = std::min(size.width(), EFL_MAX_WIDTH);
565   int height = std::min(size.height(), EFL_MAX_HEIGHT);
566   if (popup_type_ != blink::kWebPopupTypeNone) {
567     // We're a popup, honor the size request.
568     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
569     ecore_evas_resize(ee, width, height);
570   }
571
572   // Update the size of the RWH.
573   // if (requested_size_.width() != width ||
574   //    requested_size_.height() != height) {
575   // Disabled for now, will enable it while implementing InitAsPopUp (P1) API
576   host_->SendScreenRects();
577   host_->SynchronizeVisualProperties();
578   //}
579 }
580
581 void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {}
582
583 gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
584   return content_image_elm_host_;
585 }
586
587 gfx::NativeViewId RenderWidgetHostViewEfl::GetNativeViewId() const {
588   DCHECK(evas_gl_initialized_);
589   Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
590   return ecore_evas_window_get(ee);
591 }
592
593 gfx::NativeViewAccessible RenderWidgetHostViewEfl::GetNativeViewAccessible() {
594   NOTIMPLEMENTED();
595   return 0;
596 }
597
598 bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
599   return false;
600 }
601
602 void RenderWidgetHostViewEfl::EnsureSurfaceSynchronizedForLayoutTest() {
603   NOTIMPLEMENTED();
604 }
605
606 const viz::FrameSinkId& RenderWidgetHostViewEfl::GetFrameSinkId() const {
607   return viz::FrameSinkId();
608 }
609
610 const viz::LocalSurfaceId& RenderWidgetHostViewEfl::GetLocalSurfaceId() const {
611   return viz::ParentLocalSurfaceIdAllocator::InvalidLocalSurfaceId();
612 }
613
614 void RenderWidgetHostViewEfl::UpdateBackgroundColor() {
615   NOTIMPLEMENTED();
616 }
617
618 void RenderWidgetHostViewEfl::Show() {
619   evas_object_show(content_image_elm_host_);
620   host_->WasShown(false /* record_presentation_time */);
621 }
622
623 void RenderWidgetHostViewEfl::Hide() {
624   evas_object_hide(content_image_elm_host_);
625   host_->WasHidden();
626 }
627
628 bool RenderWidgetHostViewEfl::IsShowing() {
629   return evas_object_visible_get(content_image_);
630 }
631
632 gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
633   return gfx::ConvertRectToDIP(device_scale_factor_, GetViewBoundsInPix());
634 }
635
636 bool RenderWidgetHostViewEfl::LockMouse() {
637   NOTIMPLEMENTED();
638   return false;
639 }
640
641 void RenderWidgetHostViewEfl::UnlockMouse() {
642   NOTIMPLEMENTED();
643 }
644
645 void RenderWidgetHostViewEfl::Focus() {
646   elm_object_focus_set(content_image_elm_host_, EINA_TRUE);
647   evas_object_focus_set(content_image_, EINA_TRUE);
648 }
649
650 bool RenderWidgetHostViewEfl::HasFocus() const {
651   return evas_object_focus_get(content_image_);
652 }
653
654 void RenderWidgetHostViewEfl::OnDidHandleKeyEvent(
655     const blink::WebInputEvent* input_event,
656     bool processed) {
657   if (!im_context_)
658     return;
659
660   if (input_event->GetType() == blink::WebInputEvent::kKeyDown)
661     im_context_->HandleKeyEvent(processed);
662 }
663
664 void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& webcursor) {
665 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
666   if (is_loading_) {
667 // Setting native Loading cursor
668 #if defined(USE_WAYLAND)
669 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
670     ecore_wl2_window_cursor_from_name_set(GetEcoreWlWindow(), "watch");
671 #else
672     ecore_wl_window_cursor_from_name_set(GetEcoreWlWindow(), "watch");
673 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
674 #else
675     ecore_x_window_cursor_set(GetEcoreXWindow(),
676                               ecore_x_cursor_shape_get(ECORE_X_CURSOR_CLOCK));
677 #endif
678   } else {
679     CursorInfo cursor_info;
680     webcursor.GetCursorInfo(&cursor_info);
681
682 #if defined(USE_WAYLAND)
683 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
684     ecore_wl2_window_cursor_from_name_set(GetEcoreWlWindow(),
685                                           GetCursorName(cursor_info.type));
686 #else
687     ecore_wl_window_cursor_from_name_set(GetEcoreWlWindow(),
688                                          GetCursorName(cursor_info.type));
689 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
690 #else
691     int cursor_type = GetCursorType(cursor_info.type);
692     ecore_x_window_cursor_set(GetEcoreXWindow(),
693                               ecore_x_cursor_shape_get(cursor_type));
694 #endif
695   }
696 #endif  // EWK_BRINGUP
697 }
698
699 void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
700   is_loading_ = is_loading;
701   UpdateCursor(WebCursor());
702   if (disambiguation_popup_)
703     disambiguation_popup_->Dismiss();
704 }
705 void RenderWidgetHostViewEfl::SetBackgroundColor(SkColor color) {
706   // The renderer will feed its color back to us with the first CompositorFrame.
707   // We short-cut here to show a sensible color before that happens.
708   UpdateBackgroundColorFromRenderer(color);
709
710   DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
711          SkColorGetA(color) == SK_AlphaTRANSPARENT);
712   host_->SetBackgroundOpaque(SkColorGetA(color) == SK_AlphaOPAQUE);
713 }
714
715 SkColor RenderWidgetHostViewEfl::background_color() const {
716   return background_color_;
717 }
718
719 void RenderWidgetHostViewEfl::TakeFallbackContentFrom(
720     RenderWidgetHostView* view) {}
721
722 viz::SurfaceId RenderWidgetHostViewEfl::GetCurrentSurfaceId() const {
723   return viz::SurfaceId();
724 }
725
726 void RenderWidgetHostViewEfl::UpdateBackgroundColorFromRenderer(SkColor color) {
727   if (color == background_color())
728     return;
729   background_color_ = color;
730 }
731
732 void RenderWidgetHostViewEfl::TextInputStateChanged(
733     const TextInputState& params) {
734   if (!params.show_ime_if_needed) {
735     WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
736     WebContentsViewEfl* wcve = static_cast<WebContentsViewEfl*>(wci->GetView());
737     if (!wcve->UseKeyPadWithoutUserAction())
738       return;
739   } else {  // Prevent scroll and zoom for autofocus'ed elements.
740     ScrollFocusedEditableNode();
741   }
742
743   if (GetSelectionController())
744     GetSelectionController()->OnTextInputStateChanged();
745
746   if (im_context_)
747     im_context_->UpdateInputMethodState(params.type, params.can_compose_inline,
748                                         params.show_ime_if_needed);
749 }
750
751 void RenderWidgetHostViewEfl::OnTextInputInFormStateChanged(
752     bool is_in_form_tag) {
753   if (im_context_)
754     im_context_->SetIsInFormTag(is_in_form_tag);
755 }
756
757 void RenderWidgetHostViewEfl::ImeCancelComposition() {
758   if (im_context_)
759     im_context_->CancelComposition();
760 }
761
762 void RenderWidgetHostViewEfl::ImeCompositionRangeChanged(
763     const gfx::Range& range,
764     const std::vector<gfx::Rect>& character_bounds) {
765   NOTIMPLEMENTED();
766 }
767
768 void RenderWidgetHostViewEfl::FocusedNodeChanged(
769     bool is_editable_node,
770     const gfx::Rect& node_bounds_in_screen) {
771   if (GetSelectionController())
772     GetSelectionController()->HideHandleAndContextMenu();
773
774   if (im_context_ && im_context_->IsShow() &&
775       ClipboardHelperEfl::GetInstance()->IsClipboardWindowOpened()) {
776     ClipboardHelperEfl::GetInstance()->CloseClipboardWindow();
777   }
778 }
779
780 void RenderWidgetHostViewEfl::Destroy() {
781   delete this;
782 }
783
784 void RenderWidgetHostViewEfl::SetTooltipText(const base::string16& text) {}
785
786 void RenderWidgetHostViewEfl::SelectionChanged(const base::string16& text,
787                                                size_t offset,
788                                                const gfx::Range& range) {
789   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
790
791   if (!GetSelectionController())
792     return;
793
794   base::string16 selectedText;
795   if (!text.empty() && !range.is_empty())
796     selectedText = GetSelectedText();
797
798   GetSelectionController()->UpdateSelectionData(selectedText);
799 }
800
801 void RenderWidgetHostViewEfl::SelectionBoundsChanged(
802     const ViewHostMsg_SelectionBounds_Params& params) {
803   ViewHostMsg_SelectionBounds_Params guest_params(params);
804   guest_params.anchor_rect =
805       ConvertRectToPixel(device_scale_factor_, params.anchor_rect);
806   guest_params.focus_rect =
807       ConvertRectToPixel(device_scale_factor_, params.focus_rect);
808
809   if (im_context_)
810     im_context_->UpdateCaretBounds(
811         gfx::UnionRects(guest_params.anchor_rect, guest_params.focus_rect));
812
813   if (GetSelectionController())
814     GetSelectionController()->SetIsAnchorFirst(guest_params.is_anchor_first);
815 }
816
817 void RenderWidgetHostViewEfl::DidStopFlinging() {
818   EnsureEdgeEffect().Hide();
819
820   SelectionControllerEfl* controller = GetSelectionController();
821   if (!controller)
822     return;
823
824   // Show selection controls when scrolling with fling gesture ends.
825   controller->SetControlsTemporarilyHidden(false);
826 }
827
828 void RenderWidgetHostViewEfl::EvasToBlinkCords(int x,
829                                                int y,
830                                                int* view_x,
831                                                int* view_y) {
832   Evas_Coord tmpX, tmpY;
833   evas_object_geometry_get(smart_parent(), &tmpX, &tmpY, NULL, NULL);
834
835   if (view_x) {
836     *view_x = x - tmpX;
837     *view_x /= device_scale_factor_;
838   }
839
840   if (view_y) {
841     *view_y = y - tmpY;
842     *view_y /= device_scale_factor_;
843   }
844 }
845
846 void RenderWidgetHostViewEfl::SelectClosestWord(const gfx::Point& touch_point) {
847   int view_x, view_y;
848   EvasToBlinkCords(touch_point.x(), touch_point.y(), &view_x, &view_y);
849
850 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
851   // FIXME: The SelectClosestWord function was removed by
852   // commit 9720a4494c8bcd24d1f496feec5cfac7582103d2 in s-chromium
853   // It will be fixed by webview team.
854   // FIXME: http://suprem.sec.samsung.net/jira/browse/TWF-2122
855   Send(new ViewMsg_SelectClosestWord(host_->GetRoutingID(), view_x, view_y));
856 #endif  // EWK_BRINGUP
857 }
858
859 void RenderWidgetHostViewEfl::ShowDisambiguationPopup(
860     const gfx::Rect& rect_pixels,
861     const SkBitmap& zoomed_bitmap) {
862   handling_disambiguation_popup_gesture_ = true;
863   if (!disambiguation_popup_)
864     disambiguation_popup_.reset(
865         new DisambiguationPopupEfl(content_image_, this));
866
867   disambiguation_popup_->Show(rect_pixels, zoomed_bitmap);
868 }
869
870 void RenderWidgetHostViewEfl::DisambiguationPopupDismissed() {
871   handling_disambiguation_popup_gesture_ = false;
872 }
873
874 void RenderWidgetHostViewEfl::HandleDisambiguationPopupMouseDownEvent(
875     Evas_Event_Mouse_Down* evas_event) {
876   blink::WebGestureEvent tap_down_event = MakeGestureEvent(
877       blink::WebInputEvent::kGestureTapDown, content_image_, evas_event);
878   tap_down_event.data.tap.width = 0;
879   tap_down_event.data.tap.tap_count = 1;
880   SendGestureEvent(tap_down_event);
881 }
882
883 void RenderWidgetHostViewEfl::HandleDisambiguationPopupMouseUpEvent(
884     Evas_Event_Mouse_Up* evas_event) {
885   blink::WebGestureEvent tap_event = MakeGestureEvent(
886       blink::WebInputEvent::kGestureTap, content_image_, evas_event);
887   tap_event.data.tap.width = 0;
888   tap_event.data.tap.tap_count = 1;
889   SendGestureEvent(tap_event);
890 }
891
892 bool RenderWidgetHostViewEfl::CanDispatchToConsumer(
893     ui::GestureConsumer* consumer) {
894   return this == consumer;
895 }
896
897 void RenderWidgetHostViewEfl::DispatchSyntheticTouchEvent(
898     ui::TouchEvent* event) {}
899
900 void RenderWidgetHostViewEfl::DispatchGestureEvent(
901     GestureConsumer* raw_input_consumer,
902     ui::GestureEvent* event) {
903   HandleGesture(event);
904 }
905
906 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
907 void RenderWidgetHostViewEfl::CopyOutputCallback(
908     int request_id,
909     std::unique_ptr<viz::CopyOutputResult> result) {
910   if (!result->HasBitmap())
911     return;
912
913   std::unique_ptr<SkBitmap> snapshot = result->TakeBitmap();
914
915   Evas_Object* image = NULL;
916   if (!snapshot.get()->empty()) {
917     image = evas_object_image_filled_add(evas_);
918     evas_object_image_size_set(image, snapshot.get()->width(),
919                                snapshot.get()->height());
920     evas_object_image_data_copy_set(image, snapshot.get()->getPixels());
921   }
922
923   ScreenshotCapturedCallback* callback =
924       screen_capture_cb_map_->Lookup(request_id);
925
926   if (!callback)
927     return;
928
929   callback->Run(image);
930   screen_capture_cb_map_->Remove(request_id);
931 }
932 #endif  // !defined(EWK_BRINGUP)
933
934 void RenderWidgetHostViewEfl::GetSnapshotAsync(const gfx::Rect& snapshot_area,
935                                                int request_id) {
936 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
937   std::unique_ptr<viz::CopyOutputRequest> request =
938       viz::CopyOutputRequest::CreateBitmapRequest(
939           base::Bind(&RenderWidgetHostViewEfl::CopyOutputCallback,
940                      weak_factory_.GetWeakPtr(), request_id));
941   request->set_area(snapshot_area);
942 #endif  // !defined(EWK_BRINGUP)
943 }
944
945 bool RenderWidgetHostViewEfl::RequestSnapshotAsync(
946     const Eina_Rectangle rect,
947     Screenshot_Captured_Callback callback,
948     void* user_data) {
949   int width = rect.w;
950   int height = rect.h;
951   int x = rect.x;
952   int y = rect.y;
953
954   int device_x, device_y;
955   int view_x, view_y;
956
957   evas_object_geometry_get(smart_parent(), &device_x, &device_y, NULL, NULL);
958
959   if (width > device_x + GetViewBoundsInPix().width() - rect.x)
960     width = device_x + GetViewBoundsInPix().width() - rect.x;
961   if (height > device_y + GetViewBoundsInPix().height() - rect.y)
962     height = device_y + GetViewBoundsInPix().height() - rect.y;
963
964   EvasToBlinkCords(x, y, &view_x, &view_y);
965
966   width /= device_scale_factor_;
967   height /= device_scale_factor_;
968
969   ScreenshotCapturedCallback* cb =
970       new ScreenshotCapturedCallback(callback, user_data);
971
972   int cbId = screen_capture_cb_map_.Add(base::WrapUnique(cb));
973
974   GetSnapshotAsync(gfx::Rect(view_x, view_y, width, height), cbId);
975   return true;
976 }
977
978 void RenderWidgetHostViewEfl::SetWantsAnimateOnlyBeginFrames() {}
979
980 void RenderWidgetHostViewEfl::SetNeedsBeginFrames(bool needs_begin_frames) {}
981
982 void RenderWidgetHostViewEfl::DidOverscroll(
983     const ui::DidOverscrollParams& params) {
984   const gfx::Vector2dF& accumulated_overscroll = params.accumulated_overscroll;
985   const gfx::Vector2dF& latest_overscroll_delta =
986       params.latest_overscroll_delta;
987
988   if (!touch_events_enabled_)
989     return;
990
991   if (latest_overscroll_delta.x() < 0 && (int)accumulated_overscroll.x() < 0)
992     EnsureEdgeEffect().Show("edge,left");
993   if (latest_overscroll_delta.x() > 0 && (int)accumulated_overscroll.x() > 0)
994     EnsureEdgeEffect().Show("edge,right");
995   if (latest_overscroll_delta.y() < 0 && (int)accumulated_overscroll.y() < 0)
996     EnsureEdgeEffect().Show("edge,top");
997   if (latest_overscroll_delta.y() > 0 && (int)accumulated_overscroll.y() > 0)
998     EnsureEdgeEffect().Show("edge,bottom");
999 }
1000
1001 gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
1002   Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
1003   int x, y, w, h;
1004   ecore_evas_geometry_get(ee, &x, &y, &w, &h);
1005   if (current_orientation_ == 90 || current_orientation_ == 270)
1006     return gfx::ConvertRectToDIP(device_scale_factor_, gfx::Rect(x, y, h, w));
1007   return gfx::ConvertRectToDIP(device_scale_factor_, gfx::Rect(x, y, w, h));
1008 }
1009
1010 void RenderWidgetHostViewEfl::RenderProcessGone(base::TerminationStatus,
1011                                                 int error_code) {
1012   Destroy();
1013 }
1014
1015 void RenderWidgetHostViewEfl::OnParentViewResize(void* data,
1016                                                  Evas*,
1017                                                  Evas_Object* obj,
1018                                                  void*) {
1019   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1020   int x, y, width, height;
1021   evas_object_geometry_get(obj, &x, &y, &width, &height);
1022   evas_object_geometry_set(thiz->content_image_elm_host_, x, y, width, height);
1023   evas_object_image_size_set(thiz->content_image_, width, height);
1024   thiz->CreateNativeSurface(width, height);
1025   thiz->host_->SynchronizeVisualProperties();
1026 }
1027
1028 void RenderWidgetHostViewEfl::OnFocusIn(void* data,
1029                                         Evas*,
1030                                         Evas_Object*,
1031                                         void*) {
1032   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1033   if (thiz->evas_event_handler_.get())
1034     if (thiz->evas_event_handler_->HandleEvent_FocusIn())
1035       return;
1036
1037   thiz->host_->SetActive(true);
1038   thiz->host_->GotFocus();
1039   thiz->host_->WasShown(false /* record_presentation_time */);
1040
1041   Eina_Bool r = EINA_TRUE;
1042   r &= evas_object_key_grab(thiz->content_image_, "Left", 0, 0, EINA_TRUE);
1043   r &= evas_object_key_grab(thiz->content_image_, "Right", 0, 0, EINA_TRUE);
1044   r &= evas_object_key_grab(thiz->content_image_, "Up", 0, 0, EINA_TRUE);
1045   r &= evas_object_key_grab(thiz->content_image_, "Down", 0, 0, EINA_TRUE);
1046   DCHECK(r) << "Failed to grab arrow keys!";
1047 }
1048
1049 void RenderWidgetHostViewEfl::OnFocusOut(void* data,
1050                                          Evas*,
1051                                          Evas_Object*,
1052                                          void*) {
1053   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1054   if (thiz->evas_event_handler_.get())
1055     if (thiz->evas_event_handler_->HandleEvent_FocusOut())
1056       return;
1057
1058   thiz->host_->SetActive(false);
1059   thiz->host_->LostCapture();
1060   thiz->host_->Blur();
1061
1062   evas_object_key_ungrab(thiz->content_image_, "Left", 0, 0);
1063   evas_object_key_ungrab(thiz->content_image_, "Right", 0, 0);
1064   evas_object_key_ungrab(thiz->content_image_, "Up", 0, 0);
1065   evas_object_key_ungrab(thiz->content_image_, "Down", 0, 0);
1066 }
1067
1068 void RenderWidgetHostViewEfl::OnHostFocusIn(void* data, Evas_Object*, void*) {
1069   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1070   thiz->Focus();
1071 }
1072
1073 void RenderWidgetHostViewEfl::OnHostFocusOut(void* data, Evas_Object*, void*) {
1074   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1075   thiz->host_->Blur();
1076 }
1077
1078 void RenderWidgetHostViewEfl::OnMouseDown(void* data,
1079                                           Evas* evas,
1080                                           Evas_Object* obj,
1081                                           void* event_info) {
1082   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1083   if (rwhv->evas_event_handler_.get())
1084     if (rwhv->evas_event_handler_->HandleEvent_MouseDown(
1085             static_cast<Evas_Event_Mouse_Down*>(event_info)))
1086       return;
1087
1088   rwhv->Focus();
1089
1090   if (!rwhv->touch_events_enabled_) {
1091     blink::WebMouseEvent event =
1092         MakeWebMouseEvent(blink::WebInputEvent::kMouseDown, obj,
1093                           static_cast<Evas_Event_Mouse_Down*>(event_info));
1094     rwhv->host_->ForwardMouseEvent(event);
1095   } else {
1096     rwhv->ProcessTouchEvents(
1097         static_cast<Evas_Event_Mouse_Down*>(event_info)->timestamp);
1098   }
1099 }
1100
1101 void RenderWidgetHostViewEfl::OnMouseUp(void* data,
1102                                         Evas* evas,
1103                                         Evas_Object* obj,
1104                                         void* event_info) {
1105   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1106   if (rwhv->evas_event_handler_.get())
1107     if (rwhv->evas_event_handler_->HandleEvent_MouseUp(
1108             static_cast<Evas_Event_Mouse_Up*>(event_info)))
1109       return;
1110
1111   if (!rwhv->touch_events_enabled_) {
1112     blink::WebMouseEvent event =
1113         MakeWebMouseEvent(blink::WebInputEvent::kMouseUp, obj,
1114                           static_cast<Evas_Event_Mouse_Up*>(event_info));
1115     rwhv->host_->ForwardMouseEvent(event);
1116   } else {
1117     rwhv->ProcessTouchEvents(
1118         static_cast<Evas_Event_Mouse_Up*>(event_info)->timestamp);
1119   }
1120 }
1121
1122 void RenderWidgetHostViewEfl::OnMouseMove(void* data,
1123                                           Evas* evas,
1124                                           Evas_Object* obj,
1125                                           void* event_info) {
1126   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1127   if (rwhv->evas_event_handler_.get())
1128     if (rwhv->evas_event_handler_->HandleEvent_MouseMove(
1129             static_cast<Evas_Event_Mouse_Move*>(event_info)))
1130       return;
1131
1132   if (!rwhv->touch_events_enabled_) {
1133     blink::WebMouseEvent event =
1134         MakeWebMouseEvent(obj, static_cast<Evas_Event_Mouse_Move*>(event_info));
1135     rwhv->host_->ForwardMouseEvent(event);
1136   } else {
1137     rwhv->ProcessTouchEvents(
1138         static_cast<Evas_Event_Mouse_Move*>(event_info)->timestamp);
1139   }
1140 }
1141
1142 void RenderWidgetHostViewEfl::OnMultiTouchDownEvent(void* data,
1143                                                     Evas* evas,
1144                                                     Evas_Object* obj,
1145                                                     void* event_info) {
1146   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1147   CHECK(rwhv->touch_events_enabled_);
1148   rwhv->ProcessTouchEvents(
1149       static_cast<Evas_Event_Multi_Down*>(event_info)->timestamp);
1150 }
1151
1152 void RenderWidgetHostViewEfl::OnMultiTouchMoveEvent(void* data,
1153                                                     Evas* evas,
1154                                                     Evas_Object* obj,
1155                                                     void* event_info) {
1156   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1157   CHECK(rwhv->touch_events_enabled_);
1158   rwhv->ProcessTouchEvents(
1159       static_cast<Evas_Event_Multi_Move*>(event_info)->timestamp);
1160 }
1161
1162 void RenderWidgetHostViewEfl::OnMultiTouchUpEvent(void* data,
1163                                                   Evas* evas,
1164                                                   Evas_Object* obj,
1165                                                   void* event_info) {
1166   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1167   CHECK(rwhv->touch_events_enabled_);
1168   rwhv->ProcessTouchEvents(
1169       static_cast<Evas_Event_Multi_Up*>(event_info)->timestamp);
1170 }
1171
1172 void RenderWidgetHostViewEfl::OnKeyDown(void* data,
1173                                         Evas* evas,
1174                                         Evas_Object* obj,
1175                                         void* event_info) {
1176   if (!event_info)
1177     return;
1178
1179   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1180   if (rwhv->evas_event_handler_.get())
1181     if (rwhv->evas_event_handler_->HandleEvent_KeyDown(
1182             static_cast<Evas_Event_Key_Down*>(event_info)))
1183       return;
1184
1185   // When upper case letter is entered there are two events
1186   // Shift + letter key
1187   // Do not forward shift key to prevent shift keydown event.
1188   if (IsShiftKey(static_cast<Evas_Event_Key_Down*>(event_info)->key))
1189     return;
1190
1191   NativeWebKeyboardEvent n_event =
1192       MakeWebKeyboardEvent(true, static_cast<Evas_Event_Key_Down*>(event_info));
1193
1194   if (!rwhv->im_context_) {
1195     rwhv->host_->ForwardKeyboardEvent(n_event);
1196     return;
1197   }
1198
1199   // Do not forward keyevent now if there is fake key event
1200   // handling at the moment to preserve orders of events as in Webkit
1201   if (rwhv->im_context_->IsPreeditQueueEmpty() ||
1202       rwhv->im_context_->IsKeyUpQueueEmpty()) {
1203     rwhv->host_->ForwardKeyboardEvent(n_event);
1204     rwhv->im_context_->PushToKeyUpEventQueue(n_event.windows_key_code);
1205     return;
1206   }
1207
1208   rwhv->im_context_->PushToKeyDownEventQueue(n_event);
1209   rwhv->im_context_->PushToKeyUpEventQueue(n_event.windows_key_code);
1210 }
1211
1212 void RenderWidgetHostViewEfl::OnKeyUp(void* data,
1213                                       Evas* evas,
1214                                       Evas_Object* obj,
1215                                       void* event_info) {
1216   if (!event_info)
1217     return;
1218
1219   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1220   if (rwhv->evas_event_handler_.get())
1221     if (rwhv->evas_event_handler_->HandleEvent_KeyUp(
1222             static_cast<Evas_Event_Key_Up*>(event_info)))
1223       return;
1224
1225   // When upper case letter is entered there are two events
1226   // Shift + letter key
1227   // Do not forward shift key to prevent shift keyup event.
1228   if (IsShiftKey(static_cast<Evas_Event_Key_Up*>(event_info)->key))
1229     return;
1230
1231   rwhv->host_->ForwardKeyboardEvent(
1232       MakeWebKeyboardEvent(false, static_cast<Evas_Event_Key_Up*>(event_info)));
1233 }
1234
1235 #if defined(OS_TIZEN)
1236 void RenderWidgetHostViewEfl::OnHWBackEvent(void* data,
1237                                             Evas_Object* obj,
1238                                             void* event_info) {
1239   if (IsMobileProfile() || IsWearableProfile()) {
1240     RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1241     rwhv->evas_event_handler_->HandleEvent_HWBack();
1242   }
1243 }
1244 #endif
1245
1246 void RenderWidgetHostViewEfl::OnMouseWheel(void* data,
1247                                            Evas* evas,
1248                                            Evas_Object* obj,
1249                                            void* event_info) {
1250   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1251   if (rwhv->evas_event_handler_.get())
1252     if (rwhv->evas_event_handler_->HandleEvent_MouseWheel(
1253             static_cast<Evas_Event_Mouse_Wheel*>(event_info)))
1254       return;
1255
1256   if (!rwhv->touch_events_enabled_) {
1257     blink::WebMouseWheelEvent event = MakeWebMouseEvent(
1258         obj, static_cast<Evas_Event_Mouse_Wheel*>(event_info));
1259     rwhv->host_->ForwardWheelEvent(event);
1260   }
1261 }
1262
1263 void RenderWidgetHostViewEfl::ProcessTouchEvents(unsigned int timestamp) {
1264   // These constants are used to map multi touch's touch id(s).
1265   // The poorly-written Tizen API document says:
1266   //  "0 for Mouse Event and device id for Multi Event."
1267   //  "The point which comes from Mouse Event has id 0 and"
1268   //  "The point which comes from Multi Event has id that is same as Multi
1269   //  Event's device id."
1270   // This constant is to map touch id 0 to 0, or [0] -> [0]
1271   static const int kMultiTouchIDMapPart0SingleIndex = 0;
1272   // This constant is to map [13, 23] -> [1, 11]
1273   static const int kMultiTouchIDMapPart1StartIndex = 13;
1274   // This constant is to map [13, 23] -> [1, 11]
1275   static const int kMultiTouchIDMapPart1EndIndex = 23;
1276   // 13 - 1 = 12, 23 - 11 = 12
1277   static const int kMultiTouchIDMapPart1DiffValue = 12;
1278
1279   unsigned count = evas_touch_point_list_count(evas_);
1280   if (!count) {
1281     return;
1282   }
1283
1284   int id;
1285   Evas_Coord_Point pt;
1286   Evas_Touch_Point_State state;
1287   for (unsigned i = 0; i < count; ++i) {
1288     // evas_touch_point_list_nth_id_get returns [0] or [13, )
1289     // Multi touch's touch id [[0], [13, 23]] should be mapped to [[0], [1, 11]]
1290     // Internet Blame URL:
1291     //   https://groups.google.com/d/msg/mailing-enlightenment-devel/-R-ezCzpkTk/HJ0KBCdz6CgJ
1292     id = evas_touch_point_list_nth_id_get(evas_, i);
1293     DCHECK(id == kMultiTouchIDMapPart0SingleIndex ||
1294            id >= kMultiTouchIDMapPart1StartIndex);
1295
1296     if (id >= kMultiTouchIDMapPart1StartIndex &&
1297         id <= kMultiTouchIDMapPart1EndIndex) {
1298       id -= kMultiTouchIDMapPart1DiffValue;
1299     } else if (id > kMultiTouchIDMapPart1EndIndex) {
1300       LOG(WARNING) << "evas_touch_point_list_nth_id_get() returned a value "
1301                       "greater than ("
1302                    << kMultiTouchIDMapPart1EndIndex << ").";
1303     }
1304     evas_touch_point_list_nth_xy_get(evas_, i, &pt.x, &pt.y);
1305     state = evas_touch_point_list_nth_state_get(evas_, i);
1306
1307     ui::TouchEvent touch_event =
1308         MakeTouchEvent(pt, state, id, content_image_, timestamp);
1309     HandleTouchEvent(&touch_event);
1310   }
1311 }
1312
1313 void RenderWidgetHostViewEfl::SetDoubleTapSupportEnabled(bool enabled) {
1314   ui::GestureRecognizerImplEfl* gesture_recognizer_efl =
1315       static_cast<ui::GestureRecognizerImplEfl*>(gesture_recognizer_.get());
1316   DCHECK(gesture_recognizer_efl);
1317   ui::GestureProviderAura* gesture_provider_aura =
1318       gesture_recognizer_efl->GetGestureProviderForConsumer(this);
1319   gesture_provider_aura->filtered_gesture_provider_
1320       .SetDoubleTapSupportForPlatformEnabled(enabled);
1321 }
1322
1323 void RenderWidgetHostViewEfl::SetTouchEventsEnabled(bool enabled) {
1324   if (enabled == touch_events_enabled_)
1325     return;
1326
1327   touch_events_enabled_ = enabled;
1328   SetDoubleTapSupportEnabled(enabled);
1329
1330   if (enabled) {
1331     selection_controller_.reset(
1332         new SelectionControllerEfl(smart_parent_, web_contents_));
1333   } else {
1334     selection_controller_.reset();
1335   }
1336 }
1337
1338 void RenderWidgetHostViewEfl::set_magnifier(bool status) {
1339   magnifier_ = status;
1340 }
1341
1342 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
1343   ui::LatencyInfo latency_info;
1344   // The latency number should only be added if the timestamp is valid.
1345 #if !defined(EWK_BRINGUP)  // FIXME: m69 bringup
1346   if (event.TimeStampSeconds()) {
1347     const int64_t time_micros = static_cast<int64_t>(
1348         event.TimeStampSeconds() * base::Time::kMicrosecondsPerSecond);
1349     latency_info.AddLatencyNumberWithTimestamp(
1350         ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0,
1351         base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros), 1);
1352   }
1353 #endif
1354   return latency_info;
1355 }
1356
1357 void RenderWidgetHostViewEfl::SendGestureEvent(blink::WebGestureEvent& event) {
1358   HandleGesture(event);
1359   blink::WebInputEvent::Type event_type = event.GetType();
1360   if (magnifier_ && event_type == blink::WebInputEvent::kGestureScrollUpdate)
1361     return;
1362   if (host_ && event_type != blink::WebInputEvent::kUndefined)
1363     host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1364 }
1365
1366 void RenderWidgetHostViewEfl::HandleGestureBegin() {
1367   EnsureEdgeEffect().Enable();
1368 }
1369
1370 void RenderWidgetHostViewEfl::HandleGestureEnd() {
1371   // Edge effect should be disabled upon scroll end/fling start.
1372   // Gesture end comes just after those events, so it's disabled here.
1373   EnsureEdgeEffect().Disable();
1374 }
1375
1376 void RenderWidgetHostViewEfl::HandleGesture(blink::WebGestureEvent& event) {
1377   SelectionControllerEfl* controller = GetSelectionController();
1378   if (controller)
1379     controller->HandleGesture(event);
1380
1381   blink::WebInputEvent::Type event_type = event.GetType();
1382   if (event_type == blink::WebInputEvent::kGestureDoubleTap ||
1383       event_type == blink::WebInputEvent::kGesturePinchBegin ||
1384       event_type == blink::WebInputEvent::kGesturePinchEnd) {
1385     WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
1386     WebContentsViewEfl* wcve = static_cast<WebContentsViewEfl*>(wci->GetView());
1387     wcve->HandleZoomGesture(event);
1388   }
1389
1390   if ((event_type == blink::WebInputEvent::kGestureTap ||
1391        event_type == blink::WebInputEvent::kGestureTapCancel) &&
1392       !handling_disambiguation_popup_gesture_) {
1393     float size = 32.0f;  // Default value
1394
1395 #if defined(OS_TIZEN)
1396     if (IsMobileProfile() || IsWearableProfile()) {
1397       size = elm_config_finger_size_get() / device_scale_factor_;
1398     }
1399 #endif
1400
1401     event.data.tap.width = size;
1402     event.data.tap.height = size;
1403   }
1404
1405   if (event_type == blink::WebInputEvent::kGestureTapDown) {
1406     // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
1407     // event to stop any in-progress flings.
1408     blink::WebGestureEvent fling_cancel = event;
1409     fling_cancel.SetType(blink::WebInputEvent::kGestureFlingCancel);
1410 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1411     fling_cancel.source_device = blink::kWebGestureDeviceTouchscreen;
1412 #endif
1413     SendGestureEvent(fling_cancel);
1414   } else if (event_type == blink::WebInputEvent::kGestureScrollUpdate) {
1415     if (event.data.scroll_update.delta_x < 0)
1416       EnsureEdgeEffect().Hide("edge,left");
1417     else if (event.data.scroll_update.delta_x > 0)
1418       EnsureEdgeEffect().Hide("edge,right");
1419     if (event.data.scroll_update.delta_y < 0)
1420       EnsureEdgeEffect().Hide("edge,top");
1421     else if (event.data.scroll_update.delta_y > 0)
1422       EnsureEdgeEffect().Hide("edge,bottom");
1423   } else if (event_type == blink::WebInputEvent::kGesturePinchBegin) {
1424     EnsureEdgeEffect().Disable();
1425   } else if (event_type == blink::WebInputEvent::kGesturePinchEnd) {
1426     EnsureEdgeEffect().Enable();
1427   }
1428 }
1429
1430 void RenderWidgetHostViewEfl::HandleGesture(ui::GestureEvent* event) {
1431   if (event->type() == ui::ET_GESTURE_BEGIN)
1432     HandleGestureBegin();
1433   else if (event->type() == ui::ET_GESTURE_END)
1434     HandleGestureEnd();
1435
1436   blink::WebGestureEvent gesture_event = MakeWebGestureEventFromUIEvent(*event);
1437   gesture_event.SetPositionInWidget(event->location_f());
1438   gesture_event.SetPositionInScreen(event->root_location_f());
1439   SendGestureEvent(gesture_event);
1440
1441   event->SetHandled();
1442 }
1443
1444 // Based on render_widget_host_view_aura.cc::OnTouchEvent
1445 void RenderWidgetHostViewEfl::HandleTouchEvent(ui::TouchEvent* event) {
1446   if (!gesture_recognizer_->ProcessTouchEventPreDispatch(event, this)) {
1447     event->StopPropagation();
1448     return;
1449   }
1450
1451   // Update the touch event first.
1452   if (!pointer_state_.OnTouch(*event)) {
1453     event->StopPropagation();
1454     return;
1455   }
1456
1457   blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent(
1458       pointer_state_, event->may_cause_scrolling(), event->hovering());
1459   pointer_state_.CleanupRemovedTouchPoints(*event);
1460
1461   event->StopPropagation();
1462   host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
1463 }
1464
1465 void RenderWidgetHostViewEfl::ProcessAckedTouchEvent(
1466     const TouchEventWithLatencyInfo& touch,
1467     InputEventAckState ack_result) {
1468   ui::EventResult result = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
1469                                ? ui::ER_HANDLED
1470                                : ui::ER_UNHANDLED;
1471   ui::GestureRecognizer::Gestures gestures = gesture_recognizer_->AckTouchEvent(
1472       touch.event.unique_touch_event_id, result,
1473       false /* is_source_touch_event_set_non_blocking */, this);
1474   for (const auto& event : gestures)
1475     HandleGesture(event.get());
1476 }
1477
1478 EdgeEffect& RenderWidgetHostViewEfl::EnsureEdgeEffect() {
1479   if (!edge_effect_)
1480     edge_effect_ = base::WrapUnique(new EdgeEffect(content_image_elm_host_));
1481
1482   return *edge_effect_.get();
1483 }
1484
1485 void RenderWidgetHostViewEfl::OnOrientationChangeEvent(int orientation) {
1486   current_orientation_ = orientation;
1487 }
1488
1489 void RenderWidgetHostViewEfl::MoveCaret(const gfx::Point& point) {
1490 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1491   host_->MoveCaret(gfx::Point(point.x() / device_scale_factor_,
1492                               point.y() / device_scale_factor_));
1493 #endif  // !defined(EWK_BRINGUP)
1494 }
1495
1496 void RenderWidgetHostViewEfl::SetComposition(
1497     const ui::CompositionText& composition_text) {
1498 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1499   const std::vector<blink::WebCompositionUnderline>& underlines =
1500       reinterpret_cast<const std::vector<blink::WebCompositionUnderline>&>(
1501           composition_text.underlines);
1502
1503   host_->ImeSetComposition(
1504       composition_text.text, underlines, gfx::Range::InvalidRange(),
1505       composition_text.selection.start(), composition_text.selection.end());
1506 #endif  // !defined(EWK_BRINGUP)
1507 }
1508
1509 void RenderWidgetHostViewEfl::ConfirmComposition(base::string16& text) {
1510 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1511   // FIXME: EWK_BRINGUP definition should be removed.
1512   //            ImeConfirmComposition was removed
1513   host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
1514 #endif  // !defined(EWK_BRINGUP)
1515 }
1516
1517 void RenderWidgetHostViewEfl::DidCreateNewRendererCompositorFrameSink(
1518     viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
1519   renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
1520 }
1521
1522 void RenderWidgetHostViewEfl::SubmitCompositorFrame(
1523     const viz::LocalSurfaceId& local_surface_id,
1524     viz::CompositorFrame frame,
1525     base::Optional<viz::HitTestRegionList> hit_test_region_list) {
1526   last_scroll_offset_ = frame.metadata.root_scroll_offset;
1527   if (GetSelectionController()) {
1528 #if !defined(EWK_BRINGUP)
1529     GetSelectionController()->SetSelectionEditable(
1530         frame.metadata.selection.is_editable);
1531     GetSelectionController()->SetSelectionEmpty(
1532         frame.metadata.selection.is_empty_text_form_control);
1533 #endif
1534     GetSelectionController()->OnSelectionChanged(frame.metadata.selection.start,
1535                                                  frame.metadata.selection.end);
1536   }
1537
1538   SwapBrowserFrame(local_surface_id, std::move(frame));
1539 }
1540
1541 void RenderWidgetHostViewEfl::ClearCompositorFrame() {}
1542
1543 void RenderWidgetHostViewEfl::ScrollFocusedEditableNode() {
1544   // If long-pressing, do not perform zoom to focused element.
1545   if (GetSelectionController() && !GetSelectionController()->GetLongPressed()) {
1546 // The empty rect is ignored by WebViewImpl::scrollFocusedNodeIntoRect().
1547 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1548     host_->ScrollFocusedEditableNodeIntoRect(gfx::Rect());
1549 #endif  // !defined(EWK_BRINGUP)
1550   }
1551 }
1552
1553 bool RenderWidgetHostViewEfl::IsLastAvailableTextEmpty() const {
1554 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1555   return RenderWidgetHostViewBase::selection_text_.empty();
1556 #else
1557   return false;
1558 #endif
1559 }
1560
1561 bool RenderWidgetHostViewEfl::IsIMEShow() const {
1562   if (im_context_)
1563     return im_context_->IsShow();
1564
1565   return false;
1566 }
1567
1568 gfx::Rect RenderWidgetHostViewEfl::GetIMERect() const {
1569   if (im_context_)
1570     return im_context_->GetIMERect();
1571
1572   return gfx::Rect();
1573 }
1574
1575 }  // namespace content