2 Copyright (C) 2011 Samsung Electronics
3 Copyright (C) 2012 Intel Corporation. All rights reserved.
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.
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.
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.
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 "NotImplemented.h"
33 #include "PageLoadClientEfl.h"
34 #include "PagePolicyClientEfl.h"
35 #include "PageUIClientEfl.h"
36 #include "SnapshotImageGL.h"
37 #include "ViewClientEfl.h"
39 #include "WKDictionary.h"
40 #include "WKEventEfl.h"
41 #include "WKGeometry.h"
43 #include "WKPageGroup.h"
44 #include "WKPopupItem.h"
47 #include "WKViewEfl.h"
48 #include "WebContext.h"
50 #include "WebPageGroup.h"
51 #include "WebPageProxy.h"
52 #include "WebPreferences.h"
53 #include "ewk_back_forward_list_private.h"
54 #include "ewk_color_picker_private.h"
55 #include "ewk_context_menu_item_private.h"
56 #include "ewk_context_menu_private.h"
57 #include "ewk_context_private.h"
58 #include "ewk_favicon_database_private.h"
59 #include "ewk_page_group_private.h"
60 #include "ewk_popup_menu_item_private.h"
61 #include "ewk_popup_menu_private.h"
62 #include "ewk_private.h"
63 #include "ewk_security_origin_private.h"
64 #include "ewk_settings_private.h"
65 #include "ewk_window_features_private.h"
66 #include <Ecore_Evas.h>
70 #include <WebCore/CairoUtilitiesEfl.h>
71 #include <WebCore/Cursor.h>
72 #include <WebCore/NotImplemented.h>
73 #include <WebCore/PlatformContextCairo.h>
74 #include <WebKit2/WKImageCairo.h>
75 #include <wtf/MathExtras.h>
76 #include <wtf/NeverDestroyed.h>
77 #include <wtf/StdLibExtras.h>
80 #include "VibrationClientEfl.h"
83 #if ENABLE(FULLSCREEN_API)
84 #include "WebFullScreenManagerProxy.h"
87 using namespace EwkViewCallbacks;
88 using namespace WebCore;
89 using namespace WebKit;
91 static const int defaultCursorSize = 16;
93 // Auxiliary functions.
95 const char EwkView::smartClassName[] = "EWK2_View";
97 static inline void smartDataChanged(Ewk_View_Smart_Data* smartData)
101 if (smartData->changed.any)
104 smartData->changed.any = true;
105 evas_object_smart_changed(smartData->self);
108 static Evas_Smart* defaultSmartClassInstance()
110 static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(EwkView::smartClassName);
111 static Evas_Smart* smart = 0;
114 EwkView::initSmartClassInterface(api);
115 smart = evas_smart_class_new(&api.sc);
121 static inline Ewk_View_Smart_Data* toSmartData(Evas_Object* evasObject)
124 ASSERT(isEwkViewEvasObject(evasObject));
126 return static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(evasObject));
129 static inline EwkView* toEwkView(const Ewk_View_Smart_Data* smartData)
132 ASSERT(smartData->priv);
134 return smartData->priv;
137 static inline EwkView* toEwkView(const Evas_Object* evasObject)
140 ASSERT(isEwkViewEvasObject(evasObject));
142 return toEwkView(static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(evasObject)));
145 static inline void showEvasObjectsIfNeeded(const Ewk_View_Smart_Data* smartData)
149 if (evas_object_clipees_get(smartData->base.clipper))
150 evas_object_show(smartData->base.clipper);
151 evas_object_show(smartData->image);
154 // EwkViewEventHandler implementation.
156 template <Evas_Callback_Type EventType>
157 class EwkViewEventHandler {
159 static void subscribe(Evas_Object* evasObject)
161 evas_object_event_callback_add(evasObject, EventType, handleEvent, toSmartData(evasObject));
164 static void unsubscribe(Evas_Object* evasObject)
166 evas_object_event_callback_del(evasObject, EventType, handleEvent);
169 static void handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo);
173 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
175 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
176 if (smartData->api->mouse_down)
177 smartData->api->mouse_down(smartData, static_cast<Evas_Event_Mouse_Down*>(eventInfo));
181 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
183 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
184 if (smartData->api->mouse_up)
185 smartData->api->mouse_up(smartData, static_cast<Evas_Event_Mouse_Up*>(eventInfo));
189 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
191 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
192 if (smartData->api->mouse_move)
193 smartData->api->mouse_move(smartData, static_cast<Evas_Event_Mouse_Move*>(eventInfo));
197 void EwkViewEventHandler<EVAS_CALLBACK_FOCUS_IN>::handleEvent(void* data, Evas*, Evas_Object*, void*)
199 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
200 if (smartData->api->focus_in)
201 smartData->api->focus_in(smartData);
205 void EwkViewEventHandler<EVAS_CALLBACK_FOCUS_OUT>::handleEvent(void* data, Evas*, Evas_Object*, void*)
207 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
208 if (smartData->api->focus_out)
209 smartData->api->focus_out(smartData);
213 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
215 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
216 if (smartData->api->mouse_wheel)
217 smartData->api->mouse_wheel(smartData, static_cast<Evas_Event_Mouse_Wheel*>(eventInfo));
221 void EwkViewEventHandler<EVAS_CALLBACK_MOUSE_IN>::handleEvent(void* data, Evas*, Evas_Object*, void*)
223 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
224 EwkView* self = toEwkView(smartData);
226 self->updateCursor();
230 void EwkViewEventHandler<EVAS_CALLBACK_KEY_DOWN>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
232 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
233 if (smartData->api->key_down)
234 smartData->api->key_down(smartData, static_cast<Evas_Event_Key_Down*>(eventInfo));
238 void EwkViewEventHandler<EVAS_CALLBACK_KEY_UP>::handleEvent(void* data, Evas*, Evas_Object*, void* eventInfo)
240 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
241 if (smartData->api->key_up)
242 smartData->api->key_up(smartData, static_cast<Evas_Event_Key_Up*>(eventInfo));
246 void EwkViewEventHandler<EVAS_CALLBACK_SHOW>::handleEvent(void* data, Evas*, Evas_Object*, void*)
248 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
249 WKViewSetIsVisible(toEwkView(smartData)->wkView(), true);
253 void EwkViewEventHandler<EVAS_CALLBACK_HIDE>::handleEvent(void* data, Evas*, Evas_Object*, void*)
255 Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
256 WKViewSetIsVisible(toEwkView(smartData)->wkView(), false);
259 typedef HashMap<WKPageRef, Evas_Object*> WKPageToEvasObjectMap;
261 static inline WKPageToEvasObjectMap& wkPageToEvasObjectMap()
263 static NeverDestroyed<WKPageToEvasObjectMap> map;
267 // EwkView implementation.
269 EwkView::EwkView(WKViewRef view, Evas_Object* evasObject)
271 , m_evasObject(evasObject)
272 , m_context(EwkContext::findOrCreateWrapper(WKPageGetContext(wkPage())))
273 , m_pageGroup(EwkPageGroup::findOrCreateWrapper(WKPageGetPageGroup(wkPage())))
274 , m_pageLoadClient(std::make_unique<PageLoadClientEfl>(this))
275 , m_pagePolicyClient(std::make_unique<PagePolicyClientEfl>(this))
276 , m_pageUIClient(std::make_unique<PageUIClientEfl>(this))
277 , m_contextMenuClient(std::make_unique<ContextMenuClientEfl>(this))
278 , m_findClient(std::make_unique<FindClientEfl>(this))
279 , m_formClient(std::make_unique<FormClientEfl>(this))
280 , m_viewClient(std::make_unique<ViewClientEfl>(this))
281 #if ENABLE(VIBRATION)
282 , m_vibrationClient(std::make_unique<VibrationClientEfl>(this))
284 , m_backForwardList(std::make_unique<EwkBackForwardList>(WKPageGetBackForwardList(wkPage())))
285 , m_settings(std::make_unique<EwkSettings>(WKPageGroupGetPreferences(WKPageGetPageGroup(wkPage()))))
286 , m_useCustomCursor(false)
287 , m_userAgent(WKEinaSharedString(AdoptWK, WKPageCopyUserAgent(wkPage())))
288 , m_mouseEventsEnabled(false)
289 #if ENABLE(TOUCH_EVENTS)
290 , m_touchEventsEnabled(false)
291 , m_gestureRecognizer(std::make_unique<GestureRecognizer>(this))
293 , m_displayTimer(this, &EwkView::displayTimerFired)
294 , m_inputMethodContext(InputMethodContextEfl::create(this, smartData()->base.evas))
295 , m_pageViewportControllerClient(this)
296 , m_pageViewportController(page(), &m_pageViewportControllerClient)
297 , m_isAccelerated(true)
299 ASSERT(m_evasObject);
302 // FIXME: Remove when possible.
303 static_cast<WebViewEfl*>(webView())->setEwkView(this);
304 m_evasGL = EflUniquePtr<Evas_GL>(evas_gl_new(evas_object_evas_get(m_evasObject)));
306 m_evasGLContext = EvasGLContext::create(m_evasGL.get());
308 if (!m_evasGLContext) {
309 WARN("Failed to create Evas_GL, falling back to software mode.");
310 m_isAccelerated = false;
313 m_pendingSurfaceResize = m_isAccelerated;
314 WKViewInitialize(wkView());
316 WKPageGroupRef wkPageGroup = WKPageGetPageGroup(wkPage());
317 WKPreferencesRef wkPreferences = WKPageGroupGetPreferences(wkPageGroup);
318 WKPreferencesSetWebGLEnabled(wkPreferences, true);
319 WKPreferencesSetFullScreenEnabled(wkPreferences, true);
320 WKPreferencesSetWebAudioEnabled(wkPreferences, true);
321 WKPreferencesSetOfflineWebApplicationCacheEnabled(wkPreferences, true);
322 #if ENABLE(SPELLCHECK)
323 WKPreferencesSetAsynchronousSpellCheckingEnabled(wkPreferences, true);
325 WKPreferencesSetInteractiveFormValidationEnabled(wkPreferences, true);
327 // Enable mouse events by default
328 setMouseEventsEnabled(true);
330 // Listen for favicon changes.
331 EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
332 ASSERT(iconDatabase);
334 iconDatabase->watchChanges(IconChangeCallbackData(EwkView::handleFaviconChanged, this));
336 WKPageToEvasObjectMap::AddResult result = wkPageToEvasObjectMap().add(wkPage(), m_evasObject);
337 ASSERT_UNUSED(result, result.isNewEntry);
342 // Unregister icon change callback.
343 EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
344 ASSERT(iconDatabase);
346 iconDatabase->unwatchChanges(EwkView::handleFaviconChanged);
348 ASSERT(wkPageToEvasObjectMap().get(wkPage()) == m_evasObject);
349 wkPageToEvasObjectMap().remove(wkPage());
352 EwkView* EwkView::create(WKViewRef webView, Evas* canvas, Evas_Smart* smart)
354 EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, nullptr);
356 Evas_Object* evasObject = evas_object_smart_add(canvas, smart ? smart : defaultSmartClassInstance());
357 EINA_SAFETY_ON_NULL_RETURN_VAL(evasObject, nullptr);
359 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
361 evas_object_del(evasObject);
365 ASSERT(!smartData->priv);
367 smartData->priv = new EwkView(webView, evasObject);
369 return smartData->priv;
372 bool EwkView::initSmartClassInterface(Ewk_View_Smart_Class& api)
374 if (api.version != EWK_VIEW_SMART_CLASS_VERSION) {
375 EINA_LOG_CRIT("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
376 &api, api.version, EWK_VIEW_SMART_CLASS_VERSION);
380 if (!parentSmartClass.add)
381 evas_object_smart_clipped_smart_set(&parentSmartClass);
383 evas_object_smart_clipped_smart_set(&api.sc);
385 // Set Evas_Smart_Class callbacks.
386 api.sc.add = handleEvasObjectAdd;
387 api.sc.del = handleEvasObjectDelete;
388 api.sc.move = handleEvasObjectMove;
389 api.sc.resize = handleEvasObjectResize;
390 api.sc.show = handleEvasObjectShow;
391 api.sc.hide = handleEvasObjectHide;
392 api.sc.color_set = handleEvasObjectColorSet;
393 api.sc.calculate = handleEvasObjectCalculate;
394 api.sc.data = smartClassName; // It is used for type checking.
396 // Set Ewk_View_Smart_Class callbacks.
397 api.focus_in = handleEwkViewFocusIn;
398 api.focus_out = handleEwkViewFocusOut;
399 api.mouse_wheel = handleEwkViewMouseWheel;
400 api.mouse_down = handleEwkViewMouseDown;
401 api.mouse_up = handleEwkViewMouseUp;
402 api.mouse_move = handleEwkViewMouseMove;
403 api.key_down = handleEwkViewKeyDown;
404 api.key_up = handleEwkViewKeyUp;
409 Evas_Object* EwkView::toEvasObject(WKPageRef page)
412 return wkPageToEvasObjectMap().get(page);
415 WKPageRef EwkView::wkPage() const
417 return WKViewGetPage(wkView());
420 void EwkView::updateCursor()
422 Ewk_View_Smart_Data* sd = smartData();
424 if (m_useCustomCursor) {
425 Image* cursorImage = static_cast<Image*>(m_cursorIdentifier.image);
429 RefPtr<Evas_Object> cursorObject = adoptRef(cursorImage->getEvasObject(sd->base.evas));
433 IntSize cursorSize = cursorImage->size();
435 evas_object_resize(cursorObject.get(), cursorSize.width(), cursorSize.height());
437 // Get cursor hot spot.
439 cursorImage->getHotSpot(hotSpot);
441 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
442 // ecore_evas takes care of freeing the cursor object.
443 ecore_evas_object_cursor_set(ecoreEvas, cursorObject.release().leakRef(), EVAS_LAYER_MAX, hotSpot.x(), hotSpot.y());
447 const char* group = static_cast<const char*>(m_cursorIdentifier.group);
451 RefPtr<Evas_Object> cursorObject = adoptRef(edje_object_add(sd->base.evas));
453 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
454 if (!m_theme || !edje_object_file_set(cursorObject.get(), m_theme, group)) {
455 ecore_evas_object_cursor_set(ecoreEvas, 0, 0, 0, 0);
457 if (WebCore::isUsingEcoreX(sd->base.evas))
458 WebCore::applyFallbackCursor(ecoreEvas, group);
464 Evas_Coord width, height;
465 edje_object_size_min_get(cursorObject.get(), &width, &height);
466 if (width <= 0 || height <= 0)
467 edje_object_size_min_calc(cursorObject.get(), &width, &height);
468 if (width <= 0 || height <= 0) {
469 width = defaultCursorSize;
470 height = defaultCursorSize;
472 evas_object_resize(cursorObject.get(), width, height);
474 // Get cursor hot spot.
477 data = edje_object_data_get(cursorObject.get(), "hot.x");
479 hotspotX = atoi(data);
482 data = edje_object_data_get(cursorObject.get(), "hot.y");
484 hotspotY = atoi(data);
486 // ecore_evas takes care of freeing the cursor object.
487 ecore_evas_object_cursor_set(ecoreEvas, cursorObject.release().leakRef(), EVAS_LAYER_MAX, hotspotX, hotspotY);
490 void EwkView::setCursor(const Cursor& cursor)
492 if (cursor.image()) {
494 if (cursor.image() == m_cursorIdentifier.image)
497 m_cursorIdentifier.image = cursor.image();
498 m_useCustomCursor = true;
501 const char* group = cursor.platformCursor();
502 if (!group || group == m_cursorIdentifier.group)
505 m_cursorIdentifier.group = group;
506 m_useCustomCursor = false;
512 void EwkView::setDeviceScaleFactor(float scale)
514 const WKSize& deviceSize = WKViewGetSize(wkView());
515 WKPageSetCustomBackingScaleFactor(wkPage(), scale);
517 // Update internal viewport size after device-scale change.
518 WKViewSetSize(wkView(), deviceSize);
521 float EwkView::deviceScaleFactor() const
523 return WKPageGetBackingScaleFactor(wkPage());
526 AffineTransform EwkView::transformToScreen() const
528 AffineTransform transform;
530 int windowGlobalX = 0;
531 int windowGlobalY = 0;
533 Ewk_View_Smart_Data* sd = smartData();
536 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
538 Ecore_X_Window window;
539 window = ecore_evas_gl_x11_window_get(ecoreEvas);
540 // Fallback to software mode if necessary.
542 window = ecore_evas_software_x11_window_get(ecoreEvas); // Returns 0 if none.
544 int x, y; // x, y are relative to parent (in a reparenting window manager).
546 ecore_x_window_geometry_get(window, &x, &y, 0, 0);
549 window = ecore_x_window_parent_get(window);
553 transform.translate(-sd->view.x, -sd->view.y);
554 transform.translate(windowGlobalX, windowGlobalY);
559 inline Ewk_View_Smart_Data* EwkView::smartData() const
561 return toSmartData(m_evasObject);
564 inline IntSize EwkView::size() const
566 // WebPage expects a size in UI units, and not raw device units.
567 FloatSize uiSize = deviceSize();
568 uiSize.scale(1 / deviceScaleFactor());
569 return roundedIntSize(uiSize);
572 inline IntSize EwkView::deviceSize() const
574 return toIntSize(WKViewGetSize(wkView()));
577 void EwkView::displayTimerFired(Timer<EwkView>*)
579 Ewk_View_Smart_Data* sd = smartData();
581 if (m_pendingSurfaceResize) {
582 // Create a GL surface here so that Evas has no chance of painting to an empty GL surface.
583 if (!createGLSurface())
585 // Make Evas objects visible here in order not to paint empty Evas objects with black color.
586 showEvasObjectsIfNeeded(sd);
588 m_pendingSurfaceResize = false;
591 if (!m_isAccelerated) {
592 RefPtr<cairo_surface_t> surface = createSurfaceForImage(sd->image);
596 WKViewPaintToCairoSurface(wkView(), surface.get());
597 evas_object_image_data_update_add(sd->image, 0, 0, sd->view.w, sd->view.h);
601 evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context());
603 WKViewPaintToCurrentGLContext(wkView());
605 // sd->image is tied to a native surface, which is in the parent's coordinates.
606 evas_object_image_data_update_add(sd->image, sd->view.x, sd->view.y, sd->view.w, sd->view.h);
609 void EwkView::scheduleUpdateDisplay()
611 if (deviceSize().isEmpty())
614 if (!m_displayTimer.isActive())
615 m_displayTimer.startOneShot(0);
618 #if ENABLE(FULLSCREEN_API)
621 * Calls fullscreen_enter callback or falls back to default behavior and enables fullscreen mode.
623 void EwkView::enterFullScreen()
625 Ewk_View_Smart_Data* sd = smartData();
627 RefPtr<EwkSecurityOrigin> origin = EwkSecurityOrigin::create(m_url);
629 if (!sd->api->fullscreen_enter || !sd->api->fullscreen_enter(sd, origin.get())) {
630 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
631 ecore_evas_fullscreen_set(ecoreEvas, true);
637 * Calls fullscreen_exit callback or falls back to default behavior and disables fullscreen mode.
639 void EwkView::exitFullScreen()
641 Ewk_View_Smart_Data* sd = smartData();
643 if (!sd->api->fullscreen_exit || !sd->api->fullscreen_exit(sd)) {
644 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
645 ecore_evas_fullscreen_set(ecoreEvas, false);
650 WKRect EwkView::windowGeometry() const
652 Evas_Coord x, y, width, height;
653 Ewk_View_Smart_Data* sd = smartData();
655 if (!sd->api->window_geometry_get || !sd->api->window_geometry_get(sd, &x, &y, &width, &height)) {
656 Ecore_Evas* ee = ecore_evas_ecore_evas_get(sd->base.evas);
657 ecore_evas_request_geometry_get(ee, &x, &y, &width, &height);
660 return WKRectMake(x, y, width, height);
663 void EwkView::setWindowGeometry(const WKRect& rect)
665 Ewk_View_Smart_Data* sd = smartData();
667 if (!sd->api->window_geometry_set || !sd->api->window_geometry_set(sd, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)) {
668 Ecore_Evas* ee = ecore_evas_ecore_evas_get(sd->base.evas);
669 ecore_evas_move_resize(ee, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
673 const char* EwkView::title() const
675 m_title = WKEinaSharedString(AdoptWK, WKPageCopyTitle(wkPage()));
682 * This function may return @c NULL.
684 InputMethodContextEfl* EwkView::inputMethodContext()
686 return m_inputMethodContext.get();
689 const char* EwkView::themePath() const
694 void EwkView::setThemePath(const char* theme)
696 if (m_theme != theme) {
698 WKRetainPtr<WKStringRef> wkTheme = adoptWK(WKStringCreateWithUTF8CString(theme));
699 WKViewSetThemePath(wkView(), wkTheme.get());
703 void EwkView::setCustomTextEncodingName(const char* customEncoding)
705 if (m_customEncoding == customEncoding)
708 m_customEncoding = customEncoding;
709 WKRetainPtr<WKStringRef> wkCustomEncoding = adoptWK(WKStringCreateWithUTF8CString(customEncoding));
710 WKPageSetCustomTextEncodingName(wkPage(), wkCustomEncoding.get());
713 void EwkView::setUserAgent(const char* userAgent)
715 if (m_userAgent == userAgent)
718 WKRetainPtr<WKStringRef> wkUserAgent = adoptWK(WKStringCreateWithUTF8CString(userAgent));
719 WKPageSetCustomUserAgent(wkPage(), wkUserAgent.get());
721 // When 'userAgent' is 0, user agent is set as a standard user agent by WKPageSetCustomUserAgent()
722 // so m_userAgent needs to be updated using WKPageCopyUserAgent().
723 m_userAgent = WKEinaSharedString(AdoptWK, WKPageCopyUserAgent(wkPage()));
726 void EwkView::setMouseEventsEnabled(bool enabled)
728 if (m_mouseEventsEnabled == enabled)
731 m_mouseEventsEnabled = enabled;
733 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::subscribe(m_evasObject);
734 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::subscribe(m_evasObject);
735 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::subscribe(m_evasObject);
737 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::unsubscribe(m_evasObject);
738 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_UP>::unsubscribe(m_evasObject);
739 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::unsubscribe(m_evasObject);
743 #if ENABLE(TOUCH_EVENTS)
744 static WKTouchPointState toWKTouchPointState(Evas_Touch_Point_State state)
747 case EVAS_TOUCH_POINT_UP:
748 return kWKTouchPointStateTouchReleased;
749 case EVAS_TOUCH_POINT_MOVE:
750 return kWKTouchPointStateTouchMoved;
751 case EVAS_TOUCH_POINT_DOWN:
752 return kWKTouchPointStateTouchPressed;
753 case EVAS_TOUCH_POINT_STILL:
754 return kWKTouchPointStateTouchStationary;
755 case EVAS_TOUCH_POINT_CANCEL:
757 return kWKTouchPointStateTouchCancelled;
761 static WKEventModifiers toWKEventModifiers(const Evas_Modifier* modifiers)
763 WKEventModifiers wkModifiers = 0;
764 if (evas_key_modifier_is_set(modifiers, "Shift"))
765 wkModifiers |= kWKEventModifiersShiftKey;
766 if (evas_key_modifier_is_set(modifiers, "Control"))
767 wkModifiers |= kWKEventModifiersControlKey;
768 if (evas_key_modifier_is_set(modifiers, "Alt"))
769 wkModifiers |= kWKEventModifiersAltKey;
770 if (evas_key_modifier_is_set(modifiers, "Meta"))
771 wkModifiers |= kWKEventModifiersMetaKey;
776 void EwkView::feedTouchEvent(Ewk_Touch_Event_Type type, const Eina_List* points, const Evas_Modifier* modifiers)
778 unsigned length = eina_list_count(points);
779 auto touchPoints = std::make_unique<WKTypeRef[]>(length);
780 for (unsigned i = 0; i < length; ++i) {
781 Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(eina_list_nth(points, i));
783 IntPoint position(point->x, point->y);
784 touchPoints[i] = WKTouchPointCreate(point->id, toAPI(IntPoint(position)), toAPI(transformToScreen().mapPoint(position)), toWKTouchPointState(point->state), WKSizeMake(0, 0), 0, 1);
786 WKRetainPtr<WKArrayRef> wkTouchPoints(AdoptWK, WKArrayCreateAdoptingValues(touchPoints.get(), length));
788 WKViewSendTouchEvent(wkView(), adoptWK(WKTouchEventCreate(static_cast<WKEventType>(type), wkTouchPoints.get(), toWKEventModifiers(modifiers), ecore_time_get())).get());
791 void EwkView::setTouchEventsEnabled(bool enabled)
793 if (m_touchEventsEnabled == enabled)
796 m_touchEventsEnabled = enabled;
799 // FIXME: We have to connect touch callbacks with mouse and multi events
800 // because the Evas creates mouse events for first touch and multi events
801 // for second and third touches. Below codes should be fixed when the Evas
802 // supports the touch events.
803 // See https://bugs.webkit.org/show_bug.cgi?id=97785 for details.
804 Ewk_View_Smart_Data* sd = smartData();
805 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_DOWN, handleMouseDownForTouch, sd);
806 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_UP, handleMouseUpForTouch, sd);
807 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MOUSE_MOVE, handleMouseMoveForTouch, sd);
808 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_DOWN, handleMultiDownForTouch, sd);
809 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_UP, handleMultiUpForTouch, sd);
810 evas_object_event_callback_add(m_evasObject, EVAS_CALLBACK_MULTI_MOVE, handleMultiMoveForTouch, sd);
812 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_DOWN, handleMouseDownForTouch);
813 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_UP, handleMouseUpForTouch);
814 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MOUSE_MOVE, handleMouseMoveForTouch);
815 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_DOWN, handleMultiDownForTouch);
816 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_UP, handleMultiUpForTouch);
817 evas_object_event_callback_del(m_evasObject, EVAS_CALLBACK_MULTI_MOVE, handleMultiMoveForTouch);
821 void EwkView::doneWithTouchEvent(WKTouchEventRef event, bool wasEventHandled)
823 if (wasEventHandled) {
824 m_gestureRecognizer->reset();
828 m_gestureRecognizer->processTouchEvent(event);
832 bool EwkView::createGLSurface()
834 if (!m_isAccelerated)
837 static Evas_GL_Config evasGLConfig = {
840 EVAS_GL_STENCIL_NONE,
841 EVAS_GL_OPTIONS_NONE,
842 EVAS_GL_MULTISAMPLE_NONE
845 // Recreate to current size: Replaces if non-null, and frees existing surface after (OwnPtr).
846 m_evasGLSurface = EvasGLSurface::create(m_evasGL.get(), &evasGLConfig, deviceSize());
847 if (!m_evasGLSurface)
850 Evas_Native_Surface nativeSurface;
851 evas_gl_native_surface_get(m_evasGL.get(), m_evasGLSurface->surface(), &nativeSurface);
852 evas_object_image_native_surface_set(smartData()->image, &nativeSurface);
854 evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context());
856 Evas_GL_API* gl = evas_gl_api_get(m_evasGL.get());
858 WKPoint boundsEnd = WKViewUserViewportToScene(wkView(), WKPointMake(deviceSize().width(), deviceSize().height()));
859 gl->glViewport(0, 0, boundsEnd.x, boundsEnd.y);
860 gl->glClearColor(1.0, 1.0, 1.0, 0);
861 gl->glClear(GL_COLOR_BUFFER_BIT);
866 #if ENABLE(INPUT_TYPE_COLOR)
869 * Requests to show external color picker.
871 void EwkView::requestColorPicker(WKColorPickerResultListenerRef listener, const WebCore::Color& color)
873 Ewk_View_Smart_Data* sd = smartData();
874 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_request);
876 if (!sd->api->input_picker_color_request)
880 dismissColorPicker();
882 m_colorPicker = std::make_unique<EwkColorPicker>(listener, color);
884 sd->api->input_picker_color_request(sd, m_colorPicker.get());
889 * Requests to hide external color picker.
891 void EwkView::dismissColorPicker()
896 Ewk_View_Smart_Data* sd = smartData();
897 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_dismiss);
899 if (sd->api->input_picker_color_dismiss)
900 sd->api->input_picker_color_dismiss(sd);
902 m_colorPicker = nullptr;
906 void EwkView::customContextMenuItemSelected(WKContextMenuItemRef contextMenuItem)
908 Ewk_View_Smart_Data* sd = smartData();
911 if (!sd->api->custom_item_selected)
914 std::unique_ptr<EwkContextMenuItem> item = std::make_unique<EwkContextMenuItem>(contextMenuItem, nullptr);
916 sd->api->custom_item_selected(sd, item.get());
919 void EwkView::showContextMenu(WKPoint position, WKArrayRef items)
921 Ewk_View_Smart_Data* sd = smartData();
924 if (!sd->api->context_menu_show)
930 m_contextMenu = EwkContextMenu::create(this, items);
932 position = WKViewContentsToUserViewport(wkView(), position);
934 sd->api->context_menu_show(sd, position.x, position.y, m_contextMenu.get());
937 void EwkView::hideContextMenu()
942 Ewk_View_Smart_Data* sd = smartData();
945 if (sd->api->context_menu_hide)
946 sd->api->context_menu_hide(sd);
948 m_contextMenu.clear();
951 void EwkView::requestPopupMenu(WKPopupMenuListenerRef popupMenuListener, const WKRect& rect, WKPopupItemTextDirection textDirection, double pageScaleFactor, WKArrayRef items, int32_t selectedIndex)
953 Ewk_View_Smart_Data* sd = smartData();
956 ASSERT(popupMenuListener);
958 if (!sd->api->popup_menu_show)
964 m_popupMenu = std::make_unique<EwkPopupMenu>(this, popupMenuListener, items, selectedIndex);
966 WKPoint popupMenuPosition = WKViewContentsToUserViewport(wkView(), rect.origin);
968 Eina_Rectangle einaRect;
969 EINA_RECTANGLE_SET(&einaRect, popupMenuPosition.x, popupMenuPosition.y, rect.size.width, rect.size.height);
971 switch (textDirection) {
972 case kWKPopupItemTextDirectionRTL:
973 sd->api->popup_menu_show(sd, einaRect, EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, pageScaleFactor, m_popupMenu.get());
975 case EWK_TEXT_DIRECTION_LEFT_TO_RIGHT:
976 sd->api->popup_menu_show(sd, einaRect, EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, pageScaleFactor, m_popupMenu.get());
981 void EwkView::closePopupMenu()
986 Ewk_View_Smart_Data* sd = smartData();
989 if (sd->api->popup_menu_hide)
990 sd->api->popup_menu_hide(sd);
992 m_popupMenu = nullptr;
997 * Calls a smart member function for javascript alert().
999 void EwkView::requestJSAlertPopup(const WKEinaSharedString& message)
1001 Ewk_View_Smart_Data* sd = smartData();
1004 if (!sd->api->run_javascript_alert)
1007 sd->api->run_javascript_alert(sd, message);
1012 * Calls a smart member function for javascript confirm() and returns a value from the function. Returns false by default.
1014 bool EwkView::requestJSConfirmPopup(const WKEinaSharedString& message)
1016 Ewk_View_Smart_Data* sd = smartData();
1019 if (!sd->api->run_javascript_confirm)
1022 return sd->api->run_javascript_confirm(sd, message);
1027 * Calls a smart member function for javascript prompt() and returns a value from the function. Returns null string by default.
1029 WKEinaSharedString EwkView::requestJSPromptPopup(const WKEinaSharedString& message, const WKEinaSharedString& defaultValue)
1031 Ewk_View_Smart_Data* sd = smartData();
1034 if (!sd->api->run_javascript_prompt)
1035 return WKEinaSharedString();
1037 return WKEinaSharedString::adopt(sd->api->run_javascript_prompt(sd, message, defaultValue));
1040 #if ENABLE(SQL_DATABASE)
1043 * Calls exceeded_database_quota callback or falls back to default behavior returns default database quota.
1045 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)
1047 Ewk_View_Smart_Data* sd = smartData();
1050 static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
1051 if (sd->api->exceeded_database_quota)
1052 return sd->api->exceeded_database_quota(sd, databaseName.utf8().data(), displayName.utf8().data(), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
1054 return defaultQuota;
1058 WebView* EwkView::webView()
1060 return toImpl(m_webView.get());
1065 * The url of view was changed by the frame loader.
1067 * Emits signal: "url,changed" with pointer to new url string.
1069 void EwkView::informURLChange()
1071 WKRetainPtr<WKURLRef> wkActiveURL = adoptWK(WKPageCopyActiveURL(wkPage()));
1072 WKRetainPtr<WKStringRef> wkURLString = wkActiveURL ? adoptWK(WKURLCopyString(wkActiveURL.get())) : adoptWK(WKStringCreateWithUTF8CString(""));
1074 if (WKStringIsEqualToUTF8CString(wkURLString.get(), m_url))
1077 m_url = WKEinaSharedString(wkURLString.get());
1078 smartCallback<URLChanged>().call(m_url);
1080 // Update the view's favicon.
1081 smartCallback<FaviconChanged>().call();
1084 Evas_Object* EwkView::createFavicon() const
1086 EwkFaviconDatabase* iconDatabase = m_context->faviconDatabase();
1087 ASSERT(iconDatabase);
1089 return ewk_favicon_database_icon_get(iconDatabase, m_url, smartData()->base.evas);
1092 EwkWindowFeatures* EwkView::windowFeatures()
1094 if (!m_windowFeatures)
1095 m_windowFeatures = EwkWindowFeatures::create(0, this);
1097 return m_windowFeatures.get();
1100 WKPageRef EwkView::createNewPage(PassRefPtr<EwkUrlRequest>, WKDictionaryRef windowFeatures)
1102 Ewk_View_Smart_Data* sd = smartData();
1105 if (!sd->api->window_create)
1108 RefPtr<EwkWindowFeatures> ewkWindowFeatures = EwkWindowFeatures::create(windowFeatures, this);
1110 Evas_Object* newEwkView = sd->api->window_create(sd, ewkWindowFeatures.get());
1114 EwkView* newViewImpl = toEwkView(newEwkView);
1115 ASSERT(newViewImpl);
1117 newViewImpl->m_windowFeatures = ewkWindowFeatures;
1119 return static_cast<WKPageRef>(WKRetain(newViewImpl->page()));
1122 void EwkView::close()
1124 Ewk_View_Smart_Data* sd = smartData();
1127 if (!sd->api->window_close)
1130 sd->api->window_close(sd);
1133 void EwkView::handleEvasObjectAdd(Evas_Object* evasObject)
1135 const Evas_Smart* smart = evas_object_smart_smart_get(evasObject);
1136 const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
1137 const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
1140 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1143 // Allocating with 'calloc' as the API contract is that it should be deleted with 'free()'.
1144 smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
1145 evas_object_smart_data_set(evasObject, smartData);
1148 smartData->self = evasObject;
1149 smartData->api = api;
1151 parentSmartClass.add(evasObject);
1153 smartData->priv = 0; // Will be initialized further.
1155 // Create evas_object_image to draw web contents.
1156 smartData->image = evas_object_image_add(smartData->base.evas);
1157 evas_object_image_alpha_set(smartData->image, false);
1158 evas_object_image_filled_set(smartData->image, true);
1159 evas_object_smart_member_add(smartData->image, evasObject);
1160 evas_object_show(smartData->image);
1162 EwkViewEventHandler<EVAS_CALLBACK_FOCUS_IN>::subscribe(evasObject);
1163 EwkViewEventHandler<EVAS_CALLBACK_FOCUS_OUT>::subscribe(evasObject);
1164 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_IN>::subscribe(evasObject);
1165 EwkViewEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::subscribe(evasObject);
1166 EwkViewEventHandler<EVAS_CALLBACK_KEY_DOWN>::subscribe(evasObject);
1167 EwkViewEventHandler<EVAS_CALLBACK_KEY_UP>::subscribe(evasObject);
1168 EwkViewEventHandler<EVAS_CALLBACK_SHOW>::subscribe(evasObject);
1169 EwkViewEventHandler<EVAS_CALLBACK_HIDE>::subscribe(evasObject);
1172 void EwkView::handleEvasObjectDelete(Evas_Object* evasObject)
1174 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1176 ASSERT(smartData->priv); // smartData->priv is EwkView instance.
1177 delete smartData->priv;
1180 parentSmartClass.del(evasObject);
1183 void EwkView::handleEvasObjectResize(Evas_Object* evasObject, Evas_Coord width, Evas_Coord height)
1185 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1188 evas_object_resize(smartData->image, width, height);
1189 evas_object_image_size_set(smartData->image, width, height);
1190 evas_object_image_fill_set(smartData->image, 0, 0, width, height);
1192 smartData->changed.size = true;
1193 smartDataChanged(smartData);
1196 void EwkView::handleEvasObjectMove(Evas_Object* evasObject, Evas_Coord /*x*/, Evas_Coord /*y*/)
1198 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1201 smartData->changed.position = true;
1202 smartDataChanged(smartData);
1205 void EwkView::handleEvasObjectCalculate(Evas_Object* evasObject)
1207 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1210 EwkView* self = toEwkView(smartData);
1212 smartData->changed.any = false;
1214 Evas_Coord x, y, width, height;
1215 evas_object_geometry_get(evasObject, &x, &y, &width, &height);
1217 if (smartData->changed.position) {
1218 smartData->changed.position = false;
1219 smartData->view.x = x;
1220 smartData->view.y = y;
1221 evas_object_move(smartData->image, x, y);
1222 WKViewSetUserViewportTranslation(self->wkView(), x, y);
1225 if (smartData->changed.size) {
1226 smartData->changed.size = false;
1227 smartData->view.w = width;
1228 smartData->view.h = height;
1230 WKViewSetSize(self->wkView(), WKSizeMake(width, height));
1231 if (WKPageUseFixedLayout(self->wkPage()))
1232 self->pageViewportController().didChangeViewportSize(self->size());
1234 self->setNeedsSurfaceResize();
1238 void EwkView::handleEvasObjectShow(Evas_Object* evasObject)
1240 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1243 if (!toEwkView(smartData)->m_pendingSurfaceResize)
1244 showEvasObjectsIfNeeded(smartData);
1247 void EwkView::handleEvasObjectHide(Evas_Object* evasObject)
1249 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1252 evas_object_hide(smartData->base.clipper);
1253 evas_object_hide(smartData->image);
1256 void EwkView::handleEvasObjectColorSet(Evas_Object* evasObject, int red, int green, int blue, int alpha)
1258 Ewk_View_Smart_Data* smartData = toSmartData(evasObject);
1261 EwkView* view = toEwkView(smartData);
1264 alpha = clampTo(alpha, 0, 255);
1265 red = clampTo(red, 0, alpha);
1266 green = clampTo(green, 0, alpha);
1267 blue = clampTo(blue, 0, alpha);
1269 evas_object_image_alpha_set(smartData->image, alpha < 255);
1270 WKViewSetDrawsBackground(view->wkView(), red || green || blue);
1271 WKViewSetDrawsTransparentBackground(view->wkView(), alpha < 255);
1273 parentSmartClass.color_set(evasObject, red, green, blue, alpha);
1276 Eina_Bool EwkView::handleEwkViewFocusIn(Ewk_View_Smart_Data* smartData)
1278 WKViewSetIsFocused(toEwkView(smartData)->wkView(), true);
1282 Eina_Bool EwkView::handleEwkViewFocusOut(Ewk_View_Smart_Data* smartData)
1284 WKViewSetIsFocused(toEwkView(smartData)->wkView(), false);
1288 Eina_Bool EwkView::handleEwkViewMouseWheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
1290 EwkView* self = toEwkView(smartData);
1291 self->page()->handleWheelEvent(NativeWebWheelEvent(wheelEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1295 Eina_Bool EwkView::handleEwkViewMouseDown(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
1297 EwkView* self = toEwkView(smartData);
1298 self->page()->handleMouseEvent(NativeWebMouseEvent(downEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1302 Eina_Bool EwkView::handleEwkViewMouseUp(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
1304 EwkView* self = toEwkView(smartData);
1305 self->page()->handleMouseEvent(NativeWebMouseEvent(upEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1307 if (InputMethodContextEfl* inputMethodContext = self->inputMethodContext())
1308 inputMethodContext->handleMouseUpEvent(upEvent);
1313 Eina_Bool EwkView::handleEwkViewMouseMove(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
1315 EwkView* self = toEwkView(smartData);
1316 self->page()->handleMouseEvent(NativeWebMouseEvent(moveEvent, self->webView()->transformFromScene(), self->transformToScreen()));
1320 Eina_Bool EwkView::handleEwkViewKeyDown(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
1322 bool isFiltered = false;
1323 EwkView* self = toEwkView(smartData);
1324 if (InputMethodContextEfl* inputMethodContext = self->inputMethodContext())
1325 inputMethodContext->handleKeyDownEvent(downEvent, &isFiltered);
1327 self->page()->handleKeyboardEvent(NativeWebKeyboardEvent(downEvent, isFiltered));
1331 Eina_Bool EwkView::handleEwkViewKeyUp(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
1333 toEwkView(smartData)->page()->handleKeyboardEvent(NativeWebKeyboardEvent(upEvent));
1337 #if ENABLE(TOUCH_EVENTS)
1338 void EwkView::feedTouchEvents(Ewk_Touch_Event_Type type, double timestamp)
1340 Ewk_View_Smart_Data* sd = smartData();
1342 unsigned length = evas_touch_point_list_count(sd->base.evas);
1346 auto touchPoints = std::make_unique<WKTypeRef[]>(length);
1347 for (unsigned i = 0; i < length; ++i) {
1349 evas_touch_point_list_nth_xy_get(sd->base.evas, i, &x, &y);
1350 IntPoint position(x, y);
1351 Evas_Touch_Point_State state = evas_touch_point_list_nth_state_get(sd->base.evas, i);
1352 int id = evas_touch_point_list_nth_id_get(sd->base.evas, i);
1353 touchPoints[i] = WKTouchPointCreate(id, toAPI(IntPoint(position)), toAPI(transformToScreen().mapPoint(position)), toWKTouchPointState(state), WKSizeMake(0, 0), 0, 1);
1355 WKRetainPtr<WKArrayRef> wkTouchPoints(AdoptWK, WKArrayCreateAdoptingValues(touchPoints.get(), length));
1357 WKViewSendTouchEvent(wkView(), adoptWK(WKTouchEventCreate(static_cast<WKEventType>(type), wkTouchPoints.get(), toWKEventModifiers(evas_key_modifier_get(sd->base.evas)), timestamp)).get());
1360 void EwkView::handleMouseDownForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1362 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_START, static_cast<Evas_Event_Mouse_Down*>(eventInfo)->timestamp / 1000.0);
1365 void EwkView::handleMouseUpForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1367 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_END, static_cast<Evas_Event_Mouse_Up*>(eventInfo)->timestamp / 1000.0);
1370 void EwkView::handleMouseMoveForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1372 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_MOVE, static_cast<Evas_Event_Mouse_Move*>(eventInfo)->timestamp / 1000.0);
1375 void EwkView::handleMultiDownForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1377 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_START, static_cast<Evas_Event_Multi_Down*>(eventInfo)->timestamp / 1000.0);
1380 void EwkView::handleMultiUpForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1382 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_END, static_cast<Evas_Event_Multi_Up*>(eventInfo)->timestamp / 1000.0);
1385 void EwkView::handleMultiMoveForTouch(void*, Evas*, Evas_Object* ewkView, void* eventInfo)
1387 toEwkView(ewkView)->feedTouchEvents(EWK_TOUCH_MOVE, static_cast<Evas_Event_Multi_Move*>(eventInfo)->timestamp / 1000.0);
1391 void EwkView::handleFaviconChanged(const char* pageURL, void* eventInfo)
1393 EwkView* view = static_cast<EwkView*>(eventInfo);
1395 if (!view->url() || strcasecmp(view->url(), pageURL))
1398 view->smartCallback<FaviconChanged>().call();
1401 PassRefPtr<cairo_surface_t> EwkView::takeSnapshot()
1403 // Suspend all animations before taking the snapshot.
1404 WKViewSuspendActiveDOMObjectsAndAnimations(wkView());
1406 // Wait for the pending repaint events to be processed.
1407 while (m_displayTimer.isActive())
1408 ecore_main_loop_iterate();
1410 Ewk_View_Smart_Data* sd = smartData();
1411 if (m_isAccelerated) {
1412 RefPtr<cairo_surface_t> snapshot = getImageSurfaceFromFrameBuffer(0, 0, sd->view.w, sd->view.h);
1413 // Resume all animations.
1414 WKViewResumeActiveDOMObjectsAndAnimations(wkView());
1416 return snapshot.release();
1419 RefPtr<cairo_surface_t> snapshot = createSurfaceForImage(sd->image);
1420 // Resume all animations.
1421 WKViewResumeActiveDOMObjectsAndAnimations(wkView());
1423 return snapshot.release();
1426 void EwkView::didFindZoomableArea(const WKPoint& point, const WKRect& area)
1429 UNUSED_PARAM(point);
1433 bool EwkView::scrollBy(const IntSize& offset)
1435 WKPoint oldPosition = WKViewGetContentPosition(wkView());
1436 float contentScale = WKViewGetContentScaleFactor(wkView());
1438 float effectiveScale = contentScale * deviceScaleFactor();
1439 FloatPoint newPosition(oldPosition.x + offset.width() / effectiveScale, oldPosition.y + offset.height() / effectiveScale);
1441 // Update new position to the PageViewportController.
1442 newPosition = m_pageViewportController.boundContentsPositionAtScale(newPosition, contentScale);
1443 m_pageViewportController.didChangeContentsVisibility(newPosition, contentScale);
1445 // Update new position to the WKView.
1446 WKPoint position = WKPointMake(newPosition.x(), newPosition.y());
1447 WKViewSetContentPosition(wkView(), position);
1449 // If the page position has not changed, notify the caller using the return value.
1450 return !(oldPosition == position);
1453 Evas_Smart_Class EwkView::parentSmartClass = EVAS_SMART_CLASS_INIT_NULL;