b52c52e162c42f46980c04b86e0536285abc85e4
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / efl / EwkView.cpp
1 /*
2    Copyright (C) 2011 Samsung Electronics
3    Copyright (C) 2012 Intel Corporation. All rights reserved.
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "EwkView.h"
23
24 #include "ContextMenuClientEfl.h"
25 #include "EflScreenUtilities.h"
26 #include "FindClientEfl.h"
27 #include "FormClientEfl.h"
28 #include "InputMethodContextEfl.h"
29 #include "NativeWebKeyboardEvent.h"
30 #include "NativeWebMouseEvent.h"
31 #include "NativeWebWheelEvent.h"
32 #include "PageLoadClientEfl.h"
33 #include "PagePolicyClientEfl.h"
34 #include "PageUIClientEfl.h"
35 #include "PageViewportController.h"
36 #include "PageViewportControllerClientEfl.h"
37 #include "SnapshotImageGL.h"
38 #include "ViewClientEfl.h"
39 #include "WKDictionary.h"
40 #include "WKGeometry.h"
41 #include "WKNumber.h"
42 #include "WKPageGroup.h"
43 #include "WKPopupItem.h"
44 #include "WKString.h"
45 #include "WKView.h"
46 #include "WebContext.h"
47 #include "WebImage.h"
48 #include "WebPageGroup.h"
49 #include "WebPageProxy.h"
50 #include "WebPreferences.h"
51 #include "ewk_back_forward_list_private.h"
52 #include "ewk_color_picker_private.h"
53 #include "ewk_context_menu_private.h"
54 #include "ewk_context_private.h"
55 #include "ewk_favicon_database_private.h"
56 #include "ewk_popup_menu_item_private.h"
57 #include "ewk_popup_menu_private.h"
58 #include "ewk_private.h"
59 #include "ewk_security_origin_private.h"
60 #include "ewk_settings_private.h"
61 #include "ewk_view.h"
62 #include "ewk_window_features_private.h"
63 #include <Ecore_Evas.h>
64 #include <Ecore_X.h>
65 #include <Edje.h>
66 #include <Evas_GL.h>
67 #include <WebCore/CairoUtilitiesEfl.h>
68 #include <WebCore/Cursor.h>
69 #include <WebCore/PlatformContextCairo.h>
70 #include <WebKit2/WKImageCairo.h>
71 #include <wtf/MathExtras.h>
72
73 #if ENABLE(VIBRATION)
74 #include "VibrationClientEfl.h"
75 #endif
76
77 #if ENABLE(FULLSCREEN_API)
78 #include "WebFullScreenManagerProxy.h"
79 #endif
80
81 using namespace EwkViewCallbacks;
82 using namespace WebCore;
83 using namespace WebKit;
84
85 static const char smartClassName[] = "EWK2_View";
86 static const int defaultCursorSize = 16;
87
88 // Auxiliary functions.
89
90 static inline void smartDataChanged(Ewk_View_Smart_Data* smartData)
91 {
92     ASSERT(smartData);
93
94     if (smartData->changed.any)
95         return;
96
97     smartData->changed.any = true;
98     evas_object_smart_changed(smartData->self);
99 }
100
101 static Evas_Smart* defaultSmartClassInstance()
102 {
103     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(smartClassName);
104     static Evas_Smart* smart = 0;
105
106     if (!smart) {
107         EwkView::initSmartClassInterface(api);
108         smart = evas_smart_class_new(&api.sc);
109     }
110
111     return smart;
112 }
113
114 static inline Ewk_View_Smart_Data* toSmartData(Evas_Object* evasObject)
115 {
116     ASSERT(evasObject);
117     ASSERT(isEwkViewEvasObject(evasObject));
118
119     return static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(evasObject));
120 }
121
122 static inline EwkView* toEwkView(const Ewk_View_Smart_Data* smartData)
123 {
124     ASSERT(smartData);
125     ASSERT(smartData->priv);
126
127     return smartData->priv;
128 }
129
130 // EwkViewEventHandler implementation.
131
132 template <Evas_Callback_Type EventType>
133 class EwkViewEventHandler {
134 public:
135     static void subscribe(Evas_Object* evasObject)
136     {
137         evas_object_event_callback_add(evasObject, EventType, handleEvent, toSmartData(evasObject));
138     }
139
140     static void unsubscribe(Evas_Object* evasObject)
141     {
142         evas_object_event_callback_del(evasObject, EventType, handleEvent);
143     }
144
145     static void handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo);
146 };
147
148 template <>
149 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
150 {
151     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
152     if (smartData->api->mouse_down)
153         smartData->api->mouse_down(smartData, static_cast<Evas_Event_Mouse_Down*>(eventInfo));
154 }
155
156 template <>
157 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
158 {
159     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
160     if (smartData->api->mouse_up)
161         smartData->api->mouse_up(smartData, static_cast<Evas_Event_Mouse_Up*>(eventInfo));
162 }
163
164 template <>
165 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
166 {
167     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
168     if (smartData->api->mouse_move)
169         smartData->api->mouse_move(smartData, static_cast<Evas_Event_Mouse_Move*>(eventInfo));
170 }
171
172 template <>
173 void EwkViewEventHandler<EVAS_CALLBACK_FOCUS_IN>::handleEvent(void* data, Evas*, Evas_Object*, void*)
174 {
175     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
176     if (smartData->api->focus_in)
177         smartData->api->focus_in(smartData);
178 }
179
180 template <>
181 void EwkViewEventHandler<EVAS_CALLBACK_FOCUS_OUT>::handleEvent(void* data, Evas*, Evas_Object*, void*)
182 {
183     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
184     if (smartData->api->focus_out)
185         smartData->api->focus_out(smartData);
186 }
187
188 template <>
189 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
190 {
191     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
192     if (smartData->api->mouse_wheel)
193         smartData->api->mouse_wheel(smartData, static_cast<Evas_Event_Mouse_Wheel*>(eventInfo));
194 }
195
196 template <>
197 void EwkViewEventHandler<EVAS_CALLBACK_KEY_DOWN>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
198 {
199     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
200     if (smartData->api->key_down)
201         smartData->api->key_down(smartData, static_cast<Evas_Event_Key_Down*>(eventInfo));
202 }
203
204 template <>
205 void EwkViewEventHandler<EVAS_CALLBACK_KEY_UP>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
206 {
207     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
208     if (smartData->api->key_up)
209         smartData->api->key_up(smartData, static_cast<Evas_Event_Key_Up*>(eventInfo));
210 }
211
212 template <>
213 void EwkViewEventHandler<EVAS_CALLBACK_SHOW>::handleEvent(void* data, Evas*, Evas_Object*, void*)
214 {
215     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
216     toEwkView(smartData)->page()->viewStateDidChange(WebPageProxy::ViewIsVisible);
217 }
218
219 template <>
220 void EwkViewEventHandler<EVAS_CALLBACK_HIDE>::handleEvent(void* data, Evas*, Evas_Object*, void*)
221 {
222     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
223
224     // We need to pass ViewIsVisible here. viewStateDidChange() itself is responsible for actually setting the visibility to Visible or Hidden
225     // depending on what WebPageProxy::isViewVisible() returns, this simply triggers the process.
226     toEwkView(smartData)->page()->viewStateDidChange(WebPageProxy::ViewIsVisible);
227 }
228
229 // EwkView implementation.
230
231 EwkView::EwkView(Evas_Object* evasObject, PassRefPtr<EwkContext> context, WKPageGroupRef pageGroup, ViewBehavior behavior)
232     : m_evasObject(evasObject)
233     , m_context(context)
234     , m_pendingSurfaceResize(false)
235     , m_webView(adoptRef(new WebView(toImpl(m_context->wkContext()), toImpl(pageGroup), this)))
236     , m_pageLoadClient(PageLoadClientEfl::create(this))
237     , m_pagePolicyClient(PagePolicyClientEfl::create(this))
238     , m_pageUIClient(PageUIClientEfl::create(this))
239     , m_contextMenuClient(ContextMenuClientEfl::create(this))
240     , m_findClient(FindClientEfl::create(this))
241     , m_formClient(FormClientEfl::create(this))
242     , m_viewClient(ViewClientEfl::create(this))
243 #if ENABLE(VIBRATION)
244     , m_vibrationClient(VibrationClientEfl::create(this))
245 #endif
246     , m_backForwardList(EwkBackForwardList::create(WKPageGetBackForwardList(wkPage())))
247     , m_pageScaleFactor(1)
248     , m_settings(EwkSettings::create(this))
249     , m_cursorIdentifier(0)
250     , m_mouseEventsEnabled(false)
251 #if ENABLE(TOUCH_EVENTS)
252     , m_touchEventsEnabled(false)
253 #endif
254     , m_displayTimer(this, &EwkView::displayTimerFired)
255     , m_inputMethodContext(InputMethodContextEfl::create(this, smartData()->base.evas))
256     , m_pageViewportControllerClient(PageViewportControllerClientEfl::create(this))
257     , m_pageViewportController(adoptPtr(new PageViewportController(page(), m_pageViewportControllerClient.get())))
258     , m_isAccelerated(true)
259 {
260     ASSERT(m_evasObject);
261     ASSERT(m_context);
262
263     m_evasGL = adoptPtr(evas_gl_new(evas_object_evas_get(m_evasObject)));
264     if (m_evasGL)
265         m_evasGLContext = EvasGLContext::create(m_evasGL.get());
266
267     if (!m_evasGLContext) {
268         WARN("Failed to create Evas_GL, falling back to software mode.");
269         m_isAccelerated = false;
270     }
271
272     WKViewInitialize(wkView());
273
274     WKPageSetUseFixedLayout(wkPage(), behavior == DefaultBehavior);
275
276     WKPageGroupRef wkPageGroup = WKPageGetPageGroup(wkPage());
277     WKPreferencesRef wkPreferences = WKPageGroupGetPreferences(wkPageGroup);
278
279     WKPreferencesSetWebGLEnabled(wkPreferences, true);
280     WKPreferencesSetFullScreenEnabled(wkPreferences, true);
281     WKPreferencesSetWebAudioEnabled(wkPreferences, true);
282     WKPreferencesSetOfflineWebApplicationCacheEnabled(wkPreferences, true);
283 #if ENABLE(SPELLCHECK)
284     WKPreferencesSetAsynchronousSpellCheckingEnabled(wkPreferences, true);
285 #endif
286
287     // Enable mouse events by default
288     setMouseEventsEnabled(true);
289
290     // Listen for favicon changes.
291     EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
292     ASSERT(iconDatabase);
293
294     iconDatabase->watchChanges(IconChangeCallbackData(EwkView::handleFaviconChanged, this));
295 }
296
297 EwkView::~EwkView()
298 {
299     // Unregister icon change callback.
300     EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
301     ASSERT(iconDatabase);
302
303     iconDatabase->unwatchChanges(EwkView::handleFaviconChanged);
304 }
305
306 Evas_Object* EwkView::createEvasObject(Evas* canvas, Evas_Smart* smart, PassRefPtr<EwkContext> context, WKPageGroupRef pageGroupRef, ViewBehavior behavior)
307 {
308     EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
309     EINA_SAFETY_ON_NULL_RETURN_VAL(smart, 0);
310     EINA_SAFETY_ON_NULL_RETURN_VAL(context, 0);
311
312     Evas_Object* evasObject = evas_object_smart_add(canvas, smart);
313     EINA_SAFETY_ON_NULL_RETURN_VAL(evasObject, 0);
314
315     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
316     if (!smartData) {
317         evas_object_del(evasObject);
318         return 0;
319     }
320
321     ASSERT(!smartData->priv);
322
323     // Default WebPageGroup is created in WebContext constructor if the pageGroupRef is 0,
324     // so we do not need to create it here.
325     smartData->priv = new EwkView(evasObject, context, pageGroupRef, behavior);
326     return evasObject;
327 }
328
329 Evas_Object* EwkView::createEvasObject(Evas* canvas, PassRefPtr<EwkContext> context, WKPageGroupRef pageGroupRef, ViewBehavior behavior)
330 {
331     return createEvasObject(canvas, defaultSmartClassInstance(), context, pageGroupRef, behavior);
332 }
333
334 bool EwkView::initSmartClassInterface(Ewk_View_Smart_Class& api)
335 {
336     if (api.version != EWK_VIEW_SMART_CLASS_VERSION) {
337         EINA_LOG_CRIT("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
338             &api, api.version, EWK_VIEW_SMART_CLASS_VERSION);
339         return false;
340     }
341
342     if (!parentSmartClass.add)
343         evas_object_smart_clipped_smart_set(&parentSmartClass);
344
345     evas_object_smart_clipped_smart_set(&api.sc);
346
347     // Set Evas_Smart_Class callbacks.
348     api.sc.add = handleEvasObjectAdd;
349     api.sc.del = handleEvasObjectDelete;
350     api.sc.move = handleEvasObjectMove;
351     api.sc.resize = handleEvasObjectResize;
352     api.sc.show = handleEvasObjectShow;
353     api.sc.hide = handleEvasObjectHide;
354     api.sc.color_set = handleEvasObjectColorSet;
355     api.sc.calculate = handleEvasObjectCalculate;
356     api.sc.data = smartClassName; // It is used for type checking.
357
358     // Set Ewk_View_Smart_Class callbacks.
359     api.focus_in = handleEwkViewFocusIn;
360     api.focus_out = handleEwkViewFocusOut;
361     api.mouse_wheel = handleEwkViewMouseWheel;
362     api.mouse_down = handleEwkViewMouseDown;
363     api.mouse_up = handleEwkViewMouseUp;
364     api.mouse_move = handleEwkViewMouseMove;
365     api.key_down = handleEwkViewKeyDown;
366     api.key_up = handleEwkViewKeyUp;
367
368     return true;
369 }
370
371 const Evas_Object* EwkView::toEvasObject(WKPageRef page)
372 {
373     ASSERT(page);
374     return toImpl(page)->viewWidget();
375 }
376
377 WKPageRef EwkView::wkPage() const
378 {
379     return WKViewGetPage(wkView());
380 }
381
382 void EwkView::setCursor(const Cursor& cursor)
383 {
384     if (cursor.image()) {
385         // Custom cursor.
386         if (cursor.image() == m_cursorIdentifier)
387             return;
388
389         m_cursorIdentifier = cursor.image();
390
391         Ewk_View_Smart_Data* sd = smartData();
392         RefPtr<Evas_Object> cursorObject = adoptRef(cursor.image()->getEvasObject(sd->base.evas));
393         if (!cursorObject)
394             return;
395
396         // Resize cursor.
397         evas_object_resize(cursorObject.get(), cursor.image()->size().width(), cursor.image()->size().height());
398
399         // Get cursor hot spot.
400         IntPoint hotSpot;
401         cursor.image()->getHotSpot(hotSpot);
402
403         Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
404         // ecore_evas takes care of freeing the cursor object.
405         ecore_evas_object_cursor_set(ecoreEvas, cursorObject.release().leakRef(), EVAS_LAYER_MAX, hotSpot.x(), hotSpot.y());
406
407         return;
408     }
409
410     // Standard cursor.
411     const char* group = cursor.platformCursor();
412     if (!group || group == m_cursorIdentifier)
413         return;
414
415     m_cursorIdentifier = group;
416     Ewk_View_Smart_Data* sd = smartData();
417     RefPtr<Evas_Object> cursorObject = adoptRef(edje_object_add(sd->base.evas));
418
419     Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
420     if (!m_theme || !edje_object_file_set(cursorObject.get(), m_theme, group)) {
421         ecore_evas_object_cursor_set(ecoreEvas, 0, 0, 0, 0);
422 #ifdef HAVE_ECORE_X
423         if (WebCore::isUsingEcoreX(sd->base.evas))
424             WebCore::applyFallbackCursor(ecoreEvas, group);
425 #endif
426         return;
427     }
428
429     // Set cursor size.
430     Evas_Coord width, height;
431     edje_object_size_min_get(cursorObject.get(), &width, &height);
432     if (width <= 0 || height <= 0)
433         edje_object_size_min_calc(cursorObject.get(), &width, &height);
434     if (width <= 0 || height <= 0) {
435         width = defaultCursorSize;
436         height = defaultCursorSize;
437     }
438     evas_object_resize(cursorObject.get(), width, height);
439
440     // Get cursor hot spot.
441     const char* data;
442     int hotspotX = 0;
443     data = edje_object_data_get(cursorObject.get(), "hot.x");
444     if (data)
445         hotspotX = atoi(data);
446
447     int hotspotY = 0;
448     data = edje_object_data_get(cursorObject.get(), "hot.y");
449     if (data)
450         hotspotY = atoi(data);
451
452     // ecore_evas takes care of freeing the cursor object.
453     ecore_evas_object_cursor_set(ecoreEvas, cursorObject.release().leakRef(), EVAS_LAYER_MAX, hotspotX, hotspotY);
454 }
455
456 void EwkView::setDeviceScaleFactor(float scale)
457 {
458     page()->setIntrinsicDeviceScaleFactor(scale);
459
460     // Update internal viewport size after device-scale change.
461     setDeviceSize(deviceSize());
462 }
463
464 float EwkView::deviceScaleFactor() const
465 {
466     return WKPageGetBackingScaleFactor(wkPage());
467 }
468
469 void EwkView::setDeviceSize(const IntSize& deviceSize)
470 {
471     m_deviceSize = deviceSize;
472
473     DrawingAreaProxy* drawingArea = page()->drawingArea();
474     if (!drawingArea)
475         return;
476
477     drawingArea->setSize(size(), IntSize());
478     webView()->updateViewportSize();
479 }
480
481 IntSize EwkView::size() const
482 {
483     // WebPage expects a size in UI units, and not raw device units.
484     FloatSize uiSize = m_deviceSize;
485     uiSize.scale(1 / deviceScaleFactor());
486     return roundedIntSize(uiSize);
487 }
488
489 IntSize EwkView::deviceSize() const
490 {
491     return m_deviceSize;
492 }
493
494 AffineTransform EwkView::transformToScreen() const
495 {
496     AffineTransform transform;
497
498     int windowGlobalX = 0;
499     int windowGlobalY = 0;
500
501     Ewk_View_Smart_Data* sd = smartData();
502
503 #ifdef HAVE_ECORE_X
504     Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
505
506     Ecore_X_Window window;
507     window = ecore_evas_gl_x11_window_get(ecoreEvas);
508     // Fallback to software mode if necessary.
509     if (!window)
510         window = ecore_evas_software_x11_window_get(ecoreEvas); // Returns 0 if none.
511
512     int x, y; // x, y are relative to parent (in a reparenting window manager).
513     while (window) {
514         ecore_x_window_geometry_get(window, &x, &y, 0, 0);
515         windowGlobalX += x;
516         windowGlobalY += y;
517         window = ecore_x_window_parent_get(window);
518     }
519 #endif
520
521     transform.translate(-sd->view.x, -sd->view.y);
522     transform.translate(windowGlobalX, windowGlobalY);
523
524     return transform;
525 }
526
527 inline Ewk_View_Smart_Data* EwkView::smartData() const
528 {
529     return toSmartData(m_evasObject);
530 }
531
532 void EwkView::displayTimerFired(Timer<EwkView>*)
533 {
534     Ewk_View_Smart_Data* sd = smartData();
535
536     if (m_pendingSurfaceResize) {
537         // Create a GL surface here so that Evas has no chance of painting to an empty GL surface.
538         if (!createGLSurface())
539             return;
540
541         m_pendingSurfaceResize = false;
542     }
543
544     if (!m_isAccelerated) {
545         RefPtr<cairo_surface_t> surface = createSurfaceForImage(sd->image);
546         if (!surface)
547             return;
548
549         WKViewPaintToCairoSurface(wkView(), surface.get());
550         evas_object_image_data_update_add(sd->image, 0, 0, sd->view.w, sd->view.h);
551         return;
552     }
553
554     evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context());
555
556     WKViewPaintToCurrentGLContext(wkView());
557
558     // sd->image is tied to a native surface, which is in the parent's coordinates.
559     evas_object_image_data_update_add(sd->image, sd->view.x, sd->view.y, sd->view.w, sd->view.h);
560 }
561
562 void EwkView::scheduleUpdateDisplay()
563 {
564     if (m_deviceSize.isEmpty())
565         return;
566
567     if (!m_displayTimer.isActive())
568         m_displayTimer.startOneShot(0);
569 }
570
571 #if ENABLE(FULLSCREEN_API)
572 /**
573  * @internal
574  * Calls fullscreen_enter callback or falls back to default behavior and enables fullscreen mode.
575  */
576 void EwkView::enterFullScreen()
577 {
578     Ewk_View_Smart_Data* sd = smartData();
579
580     RefPtr<EwkSecurityOrigin> origin = EwkSecurityOrigin::create(m_url);
581
582     if (!sd->api->fullscreen_enter || !sd->api->fullscreen_enter(sd, origin.get())) {
583         Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
584         ecore_evas_fullscreen_set(ecoreEvas, true);
585     }
586 }
587
588 /**
589  * @internal
590  * Calls fullscreen_exit callback or falls back to default behavior and disables fullscreen mode.
591  */
592 void EwkView::exitFullScreen()
593 {
594     Ewk_View_Smart_Data* sd = smartData();
595
596     if (!sd->api->fullscreen_exit || !sd->api->fullscreen_exit(sd)) {
597         Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
598         ecore_evas_fullscreen_set(ecoreEvas, false);
599     }
600 }
601 #endif
602
603 WKRect EwkView::windowGeometry() const
604 {
605     Evas_Coord x, y, width, height;
606     Ewk_View_Smart_Data* sd = smartData();
607
608     if (!sd->api->window_geometry_get || !sd->api->window_geometry_get(sd, &x, &y, &width, &height)) {
609         Ecore_Evas* ee = ecore_evas_ecore_evas_get(sd->base.evas);
610         ecore_evas_request_geometry_get(ee, &x, &y, &width, &height);
611     }
612
613     return WKRectMake(x, y, width, height);
614 }
615
616 void EwkView::setWindowGeometry(const WKRect& rect)
617 {
618     Ewk_View_Smart_Data* sd = smartData();
619
620     if (!sd->api->window_geometry_set || !sd->api->window_geometry_set(sd, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)) {
621         Ecore_Evas* ee = ecore_evas_ecore_evas_get(sd->base.evas);
622         ecore_evas_move_resize(ee, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
623     }
624 }
625
626 void EwkView::setImageData(void* imageData, const IntSize& size)
627 {
628     Ewk_View_Smart_Data* sd = smartData();
629     if (!imageData || !sd->image)
630         return;
631
632     evas_object_resize(sd->image, size.width(), size.height());
633     evas_object_image_size_set(sd->image, size.width(), size.height());
634     evas_object_image_data_copy_set(sd->image, imageData);
635 }
636
637 bool EwkView::isFocused() const
638 {
639     return evas_object_focus_get(m_evasObject);
640 }
641
642 bool EwkView::isVisible() const
643 {
644     return evas_object_visible_get(m_evasObject);
645 }
646
647 const char* EwkView::title() const
648 {
649     m_title = WKEinaSharedString(AdoptWK, WKPageCopyTitle(wkPage()));
650
651     return m_title;
652 }
653
654 /**
655  * @internal
656  * This function may return @c NULL.
657  */
658 InputMethodContextEfl* EwkView::inputMethodContext()
659 {
660     return m_inputMethodContext.get();
661 }
662
663 const char* EwkView::themePath() const
664 {
665     return m_theme;
666 }
667
668 void EwkView::setThemePath(const char* theme)
669 {
670     if (m_theme != theme) {
671         m_theme = theme;
672         WKRetainPtr<WKStringRef> wkTheme = adoptWK(WKStringCreateWithUTF8CString(theme));
673         WKViewSetThemePath(wkView(), wkTheme.get());
674     }
675 }
676
677 const char* EwkView::customTextEncodingName() const
678 {
679     WKRetainPtr<WKStringRef> customEncoding = adoptWK(WKPageCopyCustomTextEncodingName(wkPage()));
680     if (WKStringIsEmpty(customEncoding.get()))
681         return 0;
682
683     m_customEncoding = WKEinaSharedString(customEncoding.get());
684
685     return m_customEncoding;
686 }
687
688 void EwkView::setCustomTextEncodingName(const String& encoding)
689 {
690     WKRetainPtr<WKStringRef> wkEncoding = adoptWK(toCopiedAPI(encoding));
691     WKPageSetCustomTextEncodingName(wkPage(), wkEncoding.get());
692 }
693
694 void EwkView::setMouseEventsEnabled(bool enabled)
695 {
696     if (m_mouseEventsEnabled == enabled)
697         return;
698
699     m_mouseEventsEnabled = enabled;
700     if (enabled) {
701         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::subscribe(m_evasObject);
702         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::subscribe(m_evasObject);
703         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::subscribe(m_evasObject);
704     } else {
705         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::unsubscribe(m_evasObject);
706         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::unsubscribe(m_evasObject);
707         EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::unsubscribe(m_evasObject);
708     }
709 }
710
711 #if ENABLE(TOUCH_EVENTS)
712 void EwkView::feedTouchEvent(Ewk_Touch_Event_Type type, const Eina_List* points, const Evas_Modifier* modifiers)
713 {
714     page()->handleTouchEvent(NativeWebTouchEvent(type, points, modifiers, webView()->transformFromScene(), transformToScreen(), ecore_time_get()));
715 }
716
717 void EwkView::setTouchEventsEnabled(bool enabled)
718 {
719     if (m_touchEventsEnabled == enabled)
720         return;
721
722     m_touchEventsEnabled = enabled;
723
724     if (enabled) {
725         // FIXME: We have to connect touch callbacks with mouse and multi events
726         // because the Evas creates mouse events for first touch and multi events
727         // for second and third touches. Below codes should be fixed when the Evas
728         // supports the touch events.
729         // See https://bugs.webkit.org/show_bug.cgi?id=97785 for details.
730         Ewk_View_Smart_Data* sd = smartData();
731         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_DOWN, handleTouchDown, sd);
732         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_UP, handleTouchUp, sd);
733         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_MOVE, handleTouchMove, sd);
734         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_DOWN, handleTouchDown, sd);
735         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_UP, handleTouchUp, sd);
736         evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_MOVE, handleTouchMove, sd);
737     } else {
738         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_DOWN, handleTouchDown);
739         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_UP, handleTouchUp);
740         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_MOVE, handleTouchMove);
741         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_DOWN, handleTouchDown);
742         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_UP, handleTouchUp);
743         evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_MOVE, handleTouchMove);
744     }
745 }
746 #endif
747
748 bool EwkView::createGLSurface()
749 {
750     if (!m_isAccelerated)
751         return true;
752
753     static Evas_GL_Config evasGLConfig = {
754         EVAS_GL_RGBA_8888,
755         EVAS_GL_DEPTH_BIT_8,
756         EVAS_GL_STENCIL_NONE,
757         EVAS_GL_OPTIONS_NONE,
758         EVAS_GL_MULTISAMPLE_NONE
759     };
760
761     // Recreate to current size: Replaces if non-null, and frees existing surface after (OwnPtr).
762     m_evasGLSurface = EvasGLSurface::create(m_evasGL.get(), &evasGLConfig, deviceSize());
763     if (!m_evasGLSurface)
764         return false;
765
766     Evas_Native_Surface nativeSurface;
767     evas_gl_native_surface_get(m_evasGL.get(), m_evasGLSurface->surface(), &nativeSurface);
768     evas_object_image_native_surface_set(smartData()->image, &nativeSurface);
769
770     evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context());
771
772     Evas_GL_API* gl = evas_gl_api_get(m_evasGL.get());
773
774     const WKPoint& boundsEnd = WKViewUserViewportToContents(wkView(), WKPointMake(deviceSize().width(), deviceSize().height()));
775     gl->glViewport(0, 0, boundsEnd.x, boundsEnd.y);
776     gl->glClearColor(1.0, 1.0, 1.0, 0);
777     gl->glClear(GL_COLOR_BUFFER_BIT);
778
779     return true;
780 }
781
782 #if ENABLE(INPUT_TYPE_COLOR)
783 /**
784  * @internal
785  * Requests to show external color picker.
786  */
787 void EwkView::requestColorPicker(WKColorPickerResultListenerRef listener, const WebCore::Color& color)
788 {
789     Ewk_View_Smart_Data* sd = smartData();
790     EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_request);
791
792     if (!sd->api->input_picker_color_request)
793         return;
794
795     if (m_colorPicker)
796         dismissColorPicker();
797
798     m_colorPicker = EwkColorPicker::create(listener, color);
799
800     sd->api->input_picker_color_request(sd, m_colorPicker.get());
801 }
802
803 /**
804  * @internal
805  * Requests to hide external color picker.
806  */
807 void EwkView::dismissColorPicker()
808 {
809     if (!m_colorPicker)
810         return;
811
812     Ewk_View_Smart_Data* sd = smartData();
813     EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_dismiss);
814
815     if (sd->api->input_picker_color_dismiss)
816         sd->api->input_picker_color_dismiss(sd);
817
818     m_colorPicker.clear();
819 }
820 #endif
821
822 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, RTL);
823 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, LTR);
824
825 void EwkView::showContextMenu(WebContextMenuProxyEfl* contextMenuProxy, const WebCore::IntPoint& position, const Vector<WebContextMenuItemData>& items)
826 {
827     Ewk_View_Smart_Data* sd = smartData();
828     ASSERT(sd->api);
829
830     ASSERT(contextMenuProxy);
831
832     if (!sd->api->context_menu_show)
833         return;
834
835     if (m_contextMenu)
836         hideContextMenu();
837
838     m_contextMenu = Ewk_Context_Menu::create(this, contextMenuProxy, items);
839
840     sd->api->context_menu_show(sd, position.x(), position.y(), m_contextMenu.get());
841 }
842
843 void EwkView::hideContextMenu()
844 {
845     if (!m_contextMenu)
846         return;
847
848     Ewk_View_Smart_Data* sd = smartData();
849     ASSERT(sd->api);
850
851     if (sd->api->context_menu_hide)
852         sd->api->context_menu_hide(sd);
853
854     m_contextMenu.clear();
855 }
856
857 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, kWKPopupItemTextDirectionRTL);
858 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, kWKPopupItemTextDirectionLTR);
859
860 void EwkView::requestPopupMenu(WKPopupMenuListenerRef popupMenuListener, const WKRect& rect, WKPopupItemTextDirection textDirection, double pageScaleFactor, WKArrayRef items, int32_t selectedIndex)
861 {
862     Ewk_View_Smart_Data* sd = smartData();
863     ASSERT(sd->api);
864
865     ASSERT(popupMenuListener);
866
867     if (!sd->api->popup_menu_show)
868         return;
869
870     if (m_popupMenu)
871         closePopupMenu();
872
873     m_popupMenu = EwkPopupMenu::create(this, popupMenuListener, items, selectedIndex);
874
875     Eina_Rectangle einaRect;
876     EINA_RECTANGLE_SET(&einaRect, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
877
878     sd->api->popup_menu_show(sd, einaRect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, m_popupMenu.get());
879 }
880
881 void EwkView::closePopupMenu()
882 {
883     if (!m_popupMenu)
884         return;
885
886     Ewk_View_Smart_Data* sd = smartData();
887     ASSERT(sd->api);
888
889     if (sd->api->popup_menu_hide)
890         sd->api->popup_menu_hide(sd);
891
892     m_popupMenu.clear();
893 }
894
895 /**
896  * @internal
897  * Calls a smart member function for javascript alert().
898  */
899 void EwkView::requestJSAlertPopup(const WKEinaSharedString& message)
900 {
901     Ewk_View_Smart_Data* sd = smartData();
902     ASSERT(sd->api);
903
904     if (!sd->api->run_javascript_alert)
905         return;
906
907     sd->api->run_javascript_alert(sd, message);
908 }
909
910 /**
911  * @internal
912  * Calls a smart member function for javascript confirm() and returns a value from the function. Returns false by default.
913  */
914 bool EwkView::requestJSConfirmPopup(const WKEinaSharedString& message)
915 {
916     Ewk_View_Smart_Data* sd = smartData();
917     ASSERT(sd->api);
918
919     if (!sd->api->run_javascript_confirm)
920         return false;
921
922     return sd->api->run_javascript_confirm(sd, message);
923 }
924
925 /**
926  * @internal
927  * Calls a smart member function for javascript prompt() and returns a value from the function. Returns null string by default.
928  */
929 WKEinaSharedString EwkView::requestJSPromptPopup(const WKEinaSharedString& message, const WKEinaSharedString& defaultValue)
930 {
931     Ewk_View_Smart_Data* sd = smartData();
932     ASSERT(sd->api);
933
934     if (!sd->api->run_javascript_prompt)
935         return WKEinaSharedString();
936
937     return WKEinaSharedString::adopt(sd->api->run_javascript_prompt(sd, message, defaultValue));
938 }
939
940 #if ENABLE(SQL_DATABASE)
941 /**
942  * @internal
943  * Calls exceeded_database_quota callback or falls back to default behavior returns default database quota.
944  */
945 unsigned long long EwkView::informDatabaseQuotaReached(const String& databaseName, const String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage)
946 {
947     Ewk_View_Smart_Data* sd = smartData();
948     ASSERT(sd->api);
949
950     static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
951     if (sd->api->exceeded_database_quota)
952         return sd->api->exceeded_database_quota(sd, databaseName.utf8().data(), displayName.utf8().data(), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
953
954     return defaultQuota;
955 }
956 #endif
957
958 /**
959  * @internal
960  * The url of view was changed by the frame loader.
961  *
962  * Emits signal: "url,changed" with pointer to new url string.
963  */
964 void EwkView::informURLChange()
965 {
966     WKRetainPtr<WKURLRef> wkActiveURL = adoptWK(WKPageCopyActiveURL(wkPage()));
967     WKRetainPtr<WKStringRef> wkURLString = wkActiveURL ? adoptWK(WKURLCopyString(wkActiveURL.get())) : adoptWK(WKStringCreateWithUTF8CString(""));
968
969     if (WKStringIsEqualToUTF8CString(wkURLString.get(), m_url))
970         return;
971
972     m_url = WKEinaSharedString(wkURLString.get());
973     smartCallback<URLChanged>().call(m_url);
974
975     // Update the view's favicon.
976     smartCallback<FaviconChanged>().call();
977 }
978
979 Evas_Object* EwkView::createFavicon() const
980 {
981     EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
982     ASSERT(iconDatabase);
983
984     return ewk_favicon_database_icon_get(iconDatabase, m_url, smartData()->base.evas);
985 }
986
987 EwkWindowFeatures* EwkView::windowFeatures()
988 {
989     if (!m_windowFeatures)
990         m_windowFeatures = EwkWindowFeatures::create(0, this);
991
992     return m_windowFeatures.get();
993 }
994
995 WKPageRef EwkView::createNewPage(PassRefPtr<EwkUrlRequest> request, WKDictionaryRef windowFeatures)
996 {
997     Ewk_View_Smart_Data* sd = smartData();
998     ASSERT(sd->api);
999
1000     if (!sd->api->window_create)
1001         return 0;
1002
1003     RefPtr<EwkWindowFeatures> ewkWindowFeatures = EwkWindowFeatures::create(windowFeatures, this);
1004
1005     Evas_Object* newEwkView = sd->api->window_create(sd, request->url(), ewkWindowFeatures.get());
1006     if (!newEwkView)
1007         return 0;
1008
1009     EwkView* newViewImpl = toEwkView(newEwkView);
1010     ASSERT(newViewImpl);
1011
1012     newViewImpl->m_windowFeatures = ewkWindowFeatures;
1013
1014     return static_cast<WKPageRef>(WKRetain(newViewImpl->page()));
1015 }
1016
1017 void EwkView::close()
1018 {
1019     Ewk_View_Smart_Data* sd = smartData();
1020     ASSERT(sd->api);
1021
1022     if (!sd->api->window_close)
1023         return;
1024
1025     sd->api->window_close(sd);
1026 }
1027
1028 void EwkView::handleEvasObjectAdd(Evas_Object* evasObject)
1029 {
1030     const Evas_Smart* smart = evas_object_smart_smart_get(evasObject);
1031     const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
1032     const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
1033     ASSERT(api);
1034
1035     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1036
1037     if (!smartData) {
1038         // Allocating with 'calloc' as the API contract is that it should be deleted with 'free()'.
1039         smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
1040         evas_object_smart_data_set(evasObject, smartData);
1041     }
1042
1043     smartData->self = evasObject;
1044     smartData->api = api;
1045
1046     parentSmartClass.add(evasObject);
1047
1048     smartData->priv = 0; // Will be initialized further.
1049
1050     // Create evas_object_image to draw web contents.
1051     smartData->image = evas_object_image_add(smartData->base.evas);
1052     evas_object_image_alpha_set(smartData->image, false);
1053     evas_object_image_filled_set(smartData->image, true);
1054     evas_object_smart_member_add(smartData->image, evasObject);
1055     evas_object_show(smartData->image);
1056
1057     EwkViewEventHandler<EVAS_CALLBACK_FOCUS_IN>::subscribe(evasObject);
1058     EwkViewEventHandler<EVAS_CALLBACK_FOCUS_OUT>::subscribe(evasObject);
1059     EwkViewEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::subscribe(evasObject);
1060     EwkViewEventHandler<EVAS_CALLBACK_KEY_DOWN>::subscribe(evasObject);
1061     EwkViewEventHandler<EVAS_CALLBACK_KEY_UP>::subscribe(evasObject);
1062     EwkViewEventHandler<EVAS_CALLBACK_SHOW>::subscribe(evasObject);
1063     EwkViewEventHandler<EVAS_CALLBACK_HIDE>::subscribe(evasObject);
1064 }
1065
1066 void EwkView::handleEvasObjectDelete(Evas_Object* evasObject)
1067 {
1068     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1069     if (smartData) {
1070         ASSERT(smartData->priv); // smartData->priv is EwkView instance.
1071         delete smartData->priv;
1072     }
1073
1074     parentSmartClass.del(evasObject);
1075 }
1076
1077 void EwkView::handleEvasObjectResize(Evas_Object* evasObject, Evas_Coord width, Evas_Coord height)
1078 {
1079     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1080     ASSERT(smartData);
1081
1082     evas_object_resize(smartData->image, width, height);
1083     evas_object_image_size_set(smartData->image, width, height);
1084     evas_object_image_fill_set(smartData->image, 0, 0, width, height);
1085
1086     smartData->changed.size = true;
1087     smartDataChanged(smartData);
1088 }
1089
1090 void EwkView::handleEvasObjectMove(Evas_Object* evasObject, Evas_Coord /*x*/, Evas_Coord /*y*/)
1091 {
1092     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1093     ASSERT(smartData);
1094
1095     smartData->changed.position = true;
1096     smartDataChanged(smartData);
1097 }
1098
1099 void EwkView::handleEvasObjectCalculate(Evas_Object* evasObject)
1100 {
1101     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1102     ASSERT(smartData);
1103
1104     EwkView* self = toEwkView(smartData);
1105
1106     smartData->changed.any = false;
1107
1108     Evas_Coord x, y, width, height;
1109     evas_object_geometry_get(evasObject, &x, &y, &width, &height);
1110
1111     if (smartData->changed.position) {
1112         smartData->changed.position = false;
1113         smartData->view.x = x;
1114         smartData->view.y = y;
1115         evas_object_move(smartData->image, x, y);
1116         WKViewSetUserViewportTranslation(self->wkView(), x, y);
1117     }
1118
1119     if (smartData->changed.size) {
1120         smartData->changed.size = false;
1121         smartData->view.w = width;
1122         smartData->view.h = height;
1123
1124         self->setDeviceSize(IntSize(width, height));
1125         self->setNeedsSurfaceResize();
1126     }
1127 }
1128
1129 void EwkView::handleEvasObjectShow(Evas_Object* evasObject)
1130 {
1131     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1132     ASSERT(smartData);
1133
1134     if (evas_object_clipees_get(smartData->base.clipper))
1135         evas_object_show(smartData->base.clipper);
1136     evas_object_show(smartData->image);
1137 }
1138
1139 void EwkView::handleEvasObjectHide(Evas_Object* evasObject)
1140 {
1141     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1142     ASSERT(smartData);
1143
1144     evas_object_hide(smartData->base.clipper);
1145     evas_object_hide(smartData->image);
1146 }
1147
1148 void EwkView::handleEvasObjectColorSet(Evas_Object* evasObject, int red, int green, int blue, int alpha)
1149 {
1150     Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1151     ASSERT(smartData);
1152
1153     EwkView* view = toEwkView(smartData);
1154     ASSERT(view);
1155
1156     alpha = clampTo(alpha, 0, 255);
1157     red = clampTo(red, 0, alpha);
1158     green = clampTo(green, 0, alpha);
1159     blue = clampTo(blue, 0, alpha);
1160
1161     evas_object_image_alpha_set(smartData->image, alpha < 255);
1162     WKViewSetDrawsBackground(view->wkView(), red || green || blue);
1163     WKViewSetDrawsTransparentBackground(view->wkView(), alpha < 255);
1164
1165     parentSmartClass.color_set(evasObject, red, green, blue, alpha);
1166 }
1167
1168 Eina_Bool EwkView::handleEwkViewFocusIn(Ewk_View_Smart_Data* smartData)
1169 {
1170     toEwkView(smartData)->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
1171     return true;
1172 }
1173
1174 Eina_Bool EwkView::handleEwkViewFocusOut(Ewk_View_Smart_Data* smartData)
1175 {
1176     toEwkView(smartData)->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
1177     return true;
1178 }
1179
1180 Eina_Bool EwkView::handleEwkViewMouseWheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
1181 {
1182     EwkView* self = toEwkView(smartData);
1183     self->page()->handleWheelEvent(NativeWebWheelEvent(wheelEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1184     return true;
1185 }
1186
1187 Eina_Bool EwkView::handleEwkViewMouseDown(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
1188 {
1189     EwkView* self = toEwkView(smartData);
1190     self->page()->handleMouseEvent(NativeWebMouseEvent(downEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1191     return true;
1192 }
1193
1194 Eina_Bool EwkView::handleEwkViewMouseUp(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
1195 {
1196     EwkView* self = toEwkView(smartData);
1197     self->page()->handleMouseEvent(NativeWebMouseEvent(upEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1198
1199     if (InputMethodContextEfl* inputMethodContext = self->inputMethodContext())
1200         inputMethodContext->handleMouseUpEvent(upEvent);
1201
1202     return true;
1203 }
1204
1205 Eina_Bool EwkView::handleEwkViewMouseMove(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
1206 {
1207     EwkView* self = toEwkView(smartData);
1208     self->page()->handleMouseEvent(NativeWebMouseEvent(moveEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1209     return true;
1210 }
1211
1212 Eina_Bool EwkView::handleEwkViewKeyDown(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
1213 {
1214     bool isFiltered = false;
1215     EwkView* self = toEwkView(smartData);
1216     if (InputMethodContextEfl* inputMethodContext = self->inputMethodContext())
1217         inputMethodContext->handleKeyDownEvent(downEvent, &isFiltered);
1218
1219     self->page()->handleKeyboardEvent(NativeWebKeyboardEvent(downEvent, isFiltered));
1220     return true;
1221 }
1222
1223 Eina_Bool EwkView::handleEwkViewKeyUp(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
1224 {
1225     toEwkView(smartData)->page()->handleKeyboardEvent(NativeWebKeyboardEvent(upEvent));
1226     return true;
1227 }
1228
1229 #if ENABLE(TOUCH_EVENTS)
1230 void EwkView::feedTouchEvents(Ewk_Touch_Event_Type type)
1231 {
1232     Ewk_View_Smart_Data* sd = smartData();
1233
1234     unsigned count = evas_touch_point_list_count(sd->base.evas);
1235     if (!count)
1236         return;
1237
1238     Eina_List* points = 0;
1239     for (unsigned i = 0; i < count; ++i) {
1240         Ewk_Touch_Point* point = new Ewk_Touch_Point;
1241         point->id = evas_touch_point_list_nth_id_get(sd->base.evas, i);
1242         evas_touch_point_list_nth_xy_get(sd->base.evas, i, &point->x, &point->y);
1243         point->state = evas_touch_point_list_nth_state_get(sd->base.evas, i);
1244         points = eina_list_append(points, point);
1245     }
1246
1247     feedTouchEvent(type, points, evas_key_modifier_get(sd->base.evas));
1248
1249     void* data;
1250     EINA_LIST_FREE(points, data)
1251         delete static_cast<Ewk_Touch_Point*>(data);
1252 }
1253
1254 void EwkView::handleTouchDown(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1255 {
1256     toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_START);
1257 }
1258
1259 void EwkView::handleTouchUp(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1260 {
1261     toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_END);
1262 }
1263
1264 void EwkView::handleTouchMove(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1265 {
1266     toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_MOVE);
1267 }
1268 #endif
1269
1270 void EwkView::handleFaviconChanged(const char* pageURL, void* eventInfo)
1271 {
1272     EwkView* view = static_cast<EwkView*>(eventInfo);
1273
1274     if (!view->url() || strcasecmp(view->url(), pageURL))
1275         return;
1276
1277     view->smartCallback<FaviconChanged>().call();
1278 }
1279
1280 PassRefPtr<cairo_surface_t> EwkView::takeSnapshot()
1281 {
1282     // Suspend all animations before taking the snapshot.
1283     WKViewSuspendActiveDOMObjectsAndAnimations(wkView());
1284
1285     // Wait for the pending repaint events to be processed.
1286     while (m_displayTimer.isActive())
1287         ecore_main_loop_iterate();
1288
1289     Ewk_View_Smart_Data* sd = smartData();
1290     if (!m_isAccelerated) {
1291         RefPtr<cairo_surface_t> snapshot = createSurfaceForImage(sd->image);
1292         // Resume all animations.
1293         WKViewResumeActiveDOMObjectsAndAnimations(wkView());
1294
1295         return snapshot.release();
1296     }
1297
1298     RefPtr<cairo_surface_t> snapshot = getImageSurfaceFromFrameBuffer(0, 0, sd->view.w, sd->view.h);
1299     // Resume all animations.
1300     WKViewResumeActiveDOMObjectsAndAnimations(wkView());
1301
1302     return snapshot.release();
1303 }
1304
1305 Evas_Smart_Class EwkView::parentSmartClass = EVAS_SMART_CLASS_INIT_NULL;
1306
1307 // Free Ewk View functions.
1308
1309 EwkView* toEwkView(const Evas_Object* evasObject)
1310 {
1311     ASSERT(evasObject);
1312     ASSERT(isEwkViewEvasObject(evasObject));
1313
1314     return toEwkView(static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(evasObject)));
1315 }
1316
1317 bool isEwkViewEvasObject(const Evas_Object* evasObject)
1318 {
1319     ASSERT(evasObject);
1320
1321     const char* evasObjectType = evas_object_type_get(evasObject);
1322     const Evas_Smart* evasSmart = evas_object_smart_smart_get(evasObject);
1323     if (!evasSmart) {
1324         EINA_LOG_CRIT("%p (%s) is not a smart object!", evasObject, evasObjectType ? evasObjectType : "(null)");
1325         return false;
1326     }
1327
1328     const Evas_Smart_Class* smartClass = evas_smart_class_get(evasSmart);
1329     if (!smartClass) {
1330         EINA_LOG_CRIT("%p (%s) is not a smart class object!", evasObject, evasObjectType ? evasObjectType : "(null)");
1331         return false;
1332     }
1333
1334     if (smartClass->data != smartClassName) {
1335         EINA_LOG_CRIT("%p (%s) is not of an ewk_view (need %p, got %p)!", evasObject, evasObjectType ? evasObjectType : "(null)",
1336             smartClassName, smartClass->data);
1337         return false;
1338     }
1339
1340     return true;
1341 }