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.
22 #include "EwkViewImpl.h"
24 #include "EflScreenUtilities.h"
25 #include "FindClientEfl.h"
26 #include "FormClientEfl.h"
27 #include "InputMethodContextEfl.h"
28 #include "PageClientImpl.h"
29 #include "PageLoadClientEfl.h"
30 #include "PagePolicyClientEfl.h"
31 #include "PageUIClientEfl.h"
32 #if ENABLE(WAIT_UPVERSION)
33 #include "PageViewportController.h"
34 #include "PageViewportControllerClientEfl.h"
36 #include "ResourceLoadClientEfl.h"
37 #include "WKColorPickerResultListener.h"
39 #include "WebPageProxy.h"
40 #include "WebPopupMenuProxyEfl.h"
41 #include "ewk_back_forward_list_private.h"
42 #include "ewk_context_private.h"
43 #include "ewk_favicon_database_private.h"
44 #include "ewk_popup_menu_item_private.h"
45 #include "ewk_private.h"
46 #include "ewk_settings_private.h"
48 #include "ewk_view_private.h"
49 #include <Ecore_Evas.h>
51 #include <WebCore/Cursor.h>
54 #if ENABLE(TIZEN_GEOLOCATION)
55 #include "ewk_geolocation_private.h"
57 #if ENABLE(TIZEN_MEDIA_STREAM)
58 #include "ewk_user_media_private.h"
60 #if ENABLE(TIZEN_NOTIFICATIONS)
61 #include "ewk_notification_private.h"
63 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
64 #include "WebPageGroup.h"
66 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
67 #include "ewk_web_application_icon_data_private.h"
71 using namespace WebCore;
72 using namespace WebKit;
74 static const int defaultCursorSize = 16;
76 EwkViewImpl::PageViewMap EwkViewImpl::pageViewMap;
78 void EwkViewImpl::addToPageViewMap(const Evas_Object* ewkView)
80 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
82 PageViewMap::AddResult result = pageViewMap.add(viewImpl->wkPage(), ewkView);
83 ASSERT_UNUSED(result, result.isNewEntry);
86 void EwkViewImpl::removeFromPageViewMap(const Evas_Object* ewkView)
88 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
90 ASSERT(pageViewMap.contains(viewImpl->wkPage()));
91 pageViewMap.remove(viewImpl->wkPage());
94 const Evas_Object* EwkViewImpl::viewFromPageViewMap(const WKPageRef page)
98 return pageViewMap.get(page);
101 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
102 static uint64_t generatePageGroupIdentifierID()
104 static uint64_t uniquePageGroupIdentifierID = 1;
105 return uniquePageGroupIdentifierID++;
109 EwkViewImpl::EwkViewImpl(Evas_Object* view)
112 #if USE(ACCELERATED_COMPOSITING)
118 #if ENABLE(TIZEN_ORIENTATION_EVENTS)
121 , javascriptGlobalContext(0)
122 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
125 , isWaitingForJavaScriptPopupReply(false)
128 , openPanelListener(0)
129 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
130 , certificatePolicyDecision(0)
132 #if ENABLE(TIZEN_MEDIA_STREAM)
133 , userMediaPermissionRequests(0)
135 #if ENABLE(TIZEN_GEOLOCATION)
137 , geolocationPermissionRequests(0)
139 , suspendRequested(false)
140 , suspendedPainting(false)
141 , suspendedResources(false)
142 #if ENABLE(TIZEN_NOTIFICATIONS)
144 , notificationPermissionRequests(0)
146 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
149 , isVerticalEdge(false)
150 , isHorizontalEdge(false)
151 #if ENABLE(TIZEN_GESTURE)
152 #if ENABLE(TOUCH_EVENTS)
153 , exceedTouchMoveThreshold(false)
154 , wasHandledTouchStart(false)
155 , wasHandledTouchMove(false)
157 , holdHorizontalPanning(false)
158 , holdVerticalPanning(false)
159 #endif // #if ENABLE(TIZEN_GESTURE)
160 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
161 , compositionAnimator(0)
163 #if ENABLE(TIZEN_DATALIST_ELEMENT)
166 #if ENABLE(TIZEN_APPLICATION_CACHE)
167 , applicationCachePermissionOrigin(0)
168 , isWaitingForApplicationCachePermission(false)
170 , exceededQuotaOrigin(0)
171 , isWaitingForExceededQuotaPopupReply(false)
172 #endif // #if OS(TIZEN)
174 , m_settings(Ewk_Settings::create(this))
175 , m_mouseEventsEnabled(false)
176 #if ENABLE(TOUCH_EVENTS)
177 , m_touchEventsEnabled(false)
179 , m_displayTimer(this, &EwkViewImpl::displayTimerFired)
180 , m_inputMethodContext(InputMethodContextEfl::create(this, smartData()->base.evas))
182 #if USE(TILED_BACKING_STORE)
185 #endif // #if OS(TIZEN)
189 // Enable mouse events by default
190 setMouseEventsEnabled(true);
193 javascriptPopup = adoptPtr<JavaScriptPopup>(new JavaScriptPopup(m_view));
194 openPanel = adoptPtr<OpenPanel>(new OpenPanel(m_view));
196 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
197 inputPicker = adoptPtr<InputPicker>(new InputPicker(m_view));
200 #if ENABLE(TIZEN_GESTURE)
201 #if ENABLE(TOUCH_EVENTS)
202 touchDownPoint.x = 0;
203 touchDownPoint.y = 0;
207 #if ENABLE(TIZEN_GESTURE)
208 gestureRecognizer = GestureRecognizer::create(m_view);
209 gestureClient = GestureClient::create(this);
212 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
213 const char* hideScrollbar = getenv("TIZEN_WEBKIT2_TILED_SCROLLBAR_HIDE");
214 if (hideScrollbar && atoi(hideScrollbar) == 1)
215 mainFrameScrollbarVisibility = false;
217 mainFrameScrollbarVisibility = true;
220 #if ENABLE(TIZEN_SCREEN_ORIENTATION_SUPPORT_INTERNAL)
221 orientationLock.callback = 0;
222 orientationLock.data = 0;
225 #if ENABLE(TIZEN_WEBKIT2_CREATE_VIEW_WITH_CREATED_PAGE_GROUP_WITH_IDENTIFIER)
226 String pageGroupIdentifierID = String::number(generatePageGroupIdentifierID());
227 String pageGroupIdentifier = String::format("PageGroup%s", pageGroupIdentifierID.utf8().data());
229 WKRetainPtr<WKStringRef> pageGroupIdentifierRef(AdoptWK, WKStringCreateWithUTF8CString(pageGroupIdentifier.utf8().data()));
230 pageGroup = WebPageGroup::create(toWTFString(pageGroupIdentifierRef.get()));
232 #endif // #if OS(TIZEN)
235 EwkViewImpl::~EwkViewImpl()
238 EINA_LIST_FREE(popupMenuItems, item)
239 delete static_cast<Ewk_Popup_Menu_Item*>(item);
242 if (javascriptGlobalContext)
243 JSGlobalContextRelease(javascriptGlobalContext);
245 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
246 if (webAppIconURLs) {
248 EINA_LIST_FREE(webAppIconURLs, data)
249 ewkWebAppIconDataDelete(static_cast<Ewk_Web_App_Icon_Data*>(data));
254 ewkAuthChallengeDelete(authChallenge);
256 ewkPolicyDecisionDelete(policyDecision);
258 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
259 if (certificatePolicyDecision)
260 ewkCertificatePolicyDecisionDelete(certificatePolicyDecision);
263 #if ENABLE(TIZEN_MEDIA_STREAM)
264 if (userMediaPermissionRequests)
265 ewkUserMediaDeletePermissionRequestList(userMediaPermissionRequests);
268 #if ENABLE(TIZEN_DATALIST_ELEMENT)
272 #if ENABLE(TIZEN_GEOLOCATION)
274 ewkGeolocationDeleteGeolocation(geolocation);
275 if (geolocationPermissionRequests)
276 ewkGeolocationDeletePermissionRequestList(geolocationPermissionRequests);
279 #if ENABLE(TIZEN_NOTIFICATIONS)
281 ewkNotificationDeleteNotificationList(notifications);
282 if (notificationPermissionRequests)
283 ewkNotificationDeletePermissionRequestList(notificationPermissionRequests);
286 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
287 if (compositionAnimator)
288 ecore_animator_del(compositionAnimator);
291 #if ENABLE(TIZEN_APPLICATION_CACHE)
292 if (applicationCachePermissionOrigin)
293 deleteSecurityOrigin(applicationCachePermissionOrigin);
296 if (exceededQuotaOrigin)
297 deleteSecurityOrigin(exceededQuotaOrigin);
298 #endif // #if OS(TIZEN)
301 Ewk_View_Smart_Data* EwkViewImpl::smartData() const
303 return static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_view));
306 EwkViewImpl* EwkViewImpl::fromEvasObject(const Evas_Object* view)
309 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(view));
317 * Retrieves the internal WKPage for this view.
319 WKPageRef EwkViewImpl::wkPage()
321 return toAPI(pageProxy.get());
324 void EwkViewImpl::setCursor(const Cursor& cursor)
326 Ewk_View_Smart_Data* sd = smartData();
328 const char* group = cursor.platformCursor();
329 if (!group || group == m_cursorGroup)
332 m_cursorGroup = group;
333 m_cursorObject = adoptRef(edje_object_add(sd->base.evas));
335 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
336 if (!m_theme || !edje_object_file_set(m_cursorObject.get(), m_theme, group)) {
337 m_cursorObject.clear();
339 ecore_evas_object_cursor_set(ecoreEvas, 0, 0, 0, 0);
341 if (WebCore::isUsingEcoreX(sd->base.evas))
342 WebCore::applyFallbackCursor(ecoreEvas, group);
347 Evas_Coord width, height;
348 edje_object_size_min_get(m_cursorObject.get(), &width, &height);
349 if (width <= 0 || height <= 0)
350 edje_object_size_min_calc(m_cursorObject.get(), &width, &height);
351 if (width <= 0 || height <= 0) {
352 width = defaultCursorSize;
353 height = defaultCursorSize;
355 evas_object_resize(m_cursorObject.get(), width, height);
359 data = edje_object_data_get(m_cursorObject.get(), "hot.x");
361 hotspotX = atoi(data);
364 data = edje_object_data_get(m_cursorObject.get(), "hot.y");
366 hotspotY = atoi(data);
368 ecore_evas_object_cursor_set(ecoreEvas, m_cursorObject.get(), EVAS_LAYER_MAX, hotspotX, hotspotY);
371 void EwkViewImpl::displayTimerFired(WebCore::Timer<EwkViewImpl>*)
373 Ewk_View_Smart_Data* sd = smartData();
378 #if USE(COORDINATED_GRAPHICS)
379 EWK_VIEW_IMPL_GET_OR_RETURN(sd, viewImpl);
383 for (Vector<IntRect>::iterator it = m_dirtyRects.begin(); it != m_dirtyRects.end(); ++it)
384 dirtyRegion.unite(*it);
386 m_dirtyRects.clear();
388 Vector<IntRect> rects = dirtyRegion.rects();
389 Vector<IntRect>::iterator end = rects.end();
391 for (Vector<IntRect>::iterator it = rects.begin(); it != end; ++it) {
393 #if USE(COORDINATED_GRAPHICS)
394 evas_gl_make_current(viewImpl->evasGl, viewImpl->evasGlSurface, viewImpl->evasGlContext);
395 viewImpl->pageViewportControllerClient->display(rect, IntPoint(sd->view.x, sd->view.y));
398 evas_object_image_data_update_add(sd->image, rect.x(), rect.y(), rect.width(), rect.height());
402 void EwkViewImpl::redrawRegion(const IntRect& rect)
404 if (!m_displayTimer.isActive())
405 m_displayTimer.startOneShot(0);
406 m_dirtyRects.append(rect);
411 * A download for that view was cancelled.
413 * Emits signal: "download,cancelled" with pointer to a Ewk_Download_Job.
415 void EwkViewImpl::informDownloadJobCancelled(Ewk_Download_Job* download)
417 evas_object_smart_callback_call(m_view, "download,cancelled", download);
422 * A download for that view has failed.
424 * Emits signal: "download,failed" with pointer to a Ewk_Download_Job_Error.
426 void EwkViewImpl::informDownloadJobFailed(Ewk_Download_Job* download, Ewk_Error* error)
428 Ewk_Download_Job_Error downloadError = { download, error };
429 evas_object_smart_callback_call(m_view, "download,failed", &downloadError);
434 * A download for that view finished successfully.
436 * Emits signal: "download,finished" with pointer to a Ewk_Download_Job.
438 void EwkViewImpl::informDownloadJobFinished(Ewk_Download_Job* download)
440 evas_object_smart_callback_call(m_view, "download,finished", download);
445 * A new download has been requested for that view.
447 * Emits signal: "download,request" with pointer to a Ewk_Download_Job.
449 void EwkViewImpl::informDownloadJobRequested(Ewk_Download_Job* download)
451 evas_object_smart_callback_call(m_view, "download,request", download);
456 * informs that a form request is about to be submitted.
458 * Emits signal: "form,submission,request" with pointer to Ewk_Form_Submission_Request.
460 void EwkViewImpl::informNewFormSubmissionRequest(Ewk_Form_Submission_Request* request)
462 evas_object_smart_callback_call(m_view, "form,submission,request", request);
465 #if ENABLE(FULLSCREEN_API)
468 * Calls fullscreen_enter callback or falls back to default behavior and enables fullscreen mode.
470 void EwkViewImpl::enterFullScreen()
472 Ewk_View_Smart_Data* sd = smartData();
474 if (!sd->api->fullscreen_enter || !sd->api->fullscreen_enter(sd)) {
475 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
476 ecore_evas_fullscreen_set(ecoreEvas, true);
482 * Calls fullscreen_exit callback or falls back to default behavior and disables fullscreen mode.
484 void EwkViewImpl::exitFullScreen()
486 Ewk_View_Smart_Data* sd = smartData();
488 if (!sd->api->fullscreen_exit || !sd->api->fullscreen_exit(sd)) {
489 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
490 ecore_evas_fullscreen_set(ecoreEvas, false);
495 void EwkViewImpl::setImageData(void* imageData, const IntSize& size)
497 Ewk_View_Smart_Data* sd = smartData();
498 if (!imageData || !sd->image)
501 evas_object_resize(sd->image, size.width(), size.height());
502 evas_object_image_size_set(sd->image, size.width(), size.height());
503 evas_object_image_data_copy_set(sd->image, imageData);
506 #if ENABLE(INPUT_TYPE_COLOR)
507 bool EwkViewImpl::setColorPickerColor(const WebCore::Color& color)
509 if (!m_colorPickerResultListener)
512 WKRetainPtr<WKStringRef> colorString(AdoptWK, WKStringCreateWithUTF8CString(color.serialized().utf8().data()));
513 WKColorPickerResultListenerSetColor(m_colorPickerResultListener.get(), colorString.get());
514 m_colorPickerResultListener.clear();
522 * informs load failed with error information.
524 * Emits signal: "load,error" with pointer to Ewk_Error.
526 void EwkViewImpl::informLoadError(Ewk_Error* error)
528 evas_object_smart_callback_call(m_view, "load,error", error);
533 * informs load finished.
535 * Emits signal: "load,finished".
537 void EwkViewImpl::informLoadFinished()
540 evas_object_smart_callback_call(m_view, "load,finished", 0);
543 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
544 pageProxy->setLoadingFinished(true);
546 if (pageClient->wasViewportFitsToContent())
547 pageClient->fitViewportToContent();
549 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
550 ewk_view_form_password_data_fill(m_view);
553 if (!suspendRequested)
556 suspendRequested = false;
558 if (!suspendedPainting) {
559 pageProxy->suspendPainting();
560 suspendedPainting = true;
562 if (!suspendedResources) {
563 pageProxy->suspendJavaScriptAndResource();
564 suspendedResources = true;
571 * informs load progress changed.
573 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
575 void EwkViewImpl::informLoadProgress(double progress)
577 evas_object_smart_callback_call(m_view, "load,progress", &progress);
582 * informs view provisional load failed with error information.
584 * Emits signal: "load,provisional,failed" with pointer to Ewk_Error.
586 void EwkViewImpl::informProvisionalLoadFailed(Ewk_Error* error)
588 evas_object_smart_callback_call(m_view, "load,provisional,failed", error);
591 #if ENABLE(WAIT_UPVERSION)
592 #if USE(TILED_BACKING_STORE)
593 void EwkViewImpl::informLoadCommitted()
595 pageViewportController->didCommitLoad();
602 * informs view received redirect for provisional load.
604 * Emits signal: "load,provisional,redirect".
606 void EwkViewImpl::informProvisionalLoadRedirect()
609 evas_object_smart_callback_call(m_view, "load,provisional,redirect", 0);
614 * informs view provisional load started.
616 * Emits signal: "load,provisional,started".
618 void EwkViewImpl::informProvisionalLoadStarted()
621 evas_object_smart_callback_call(m_view, "load,started", 0);
624 #if ENABLE(TIZEN_DRAG_SUPPORT)
625 if (pageClient->isDragMode())
626 pageClient->setDragMode(false);
629 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
630 pageProxy->setLoadingFinished(false);
634 evas_object_smart_callback_call(m_view, "load,provisional,started", 0);
639 * informs that a navigation policy decision should be taken.
641 * Emits signal: "policy,decision,navigation".
643 void EwkViewImpl::informNavigationPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
645 evas_object_smart_callback_call(m_view, "policy,decision,navigation", decision);
650 * informs that a new window policy decision should be taken.
652 * Emits signal: "policy,decision,new,window".
654 void EwkViewImpl::informNewWindowPolicyDecision(Ewk_Navigation_Policy_Decision* decision)
656 evas_object_smart_callback_call(m_view, "policy,decision,new,window", decision);
661 * Load was initiated for a resource in the view.
663 * Emits signal: "resource,request,new" with pointer to resource request.
665 void EwkViewImpl::informResourceLoadStarted(Ewk_Resource* resource, Ewk_Url_Request* request)
667 Ewk_Resource_Request resourceRequest = {resource, request, 0};
669 evas_object_smart_callback_call(m_view, "resource,request,new", &resourceRequest);
674 * Received a response to a resource load request in the view.
676 * Emits signal: "resource,request,response" with pointer to resource response.
678 void EwkViewImpl::informResourceLoadResponse(Ewk_Resource* resource, Ewk_Url_Response* response)
680 Ewk_Resource_Load_Response resourceLoadResponse = {resource, response};
681 evas_object_smart_callback_call(m_view, "resource,request,response", &resourceLoadResponse);
686 * Failed loading a resource in the view.
688 * Emits signal: "resource,request,finished" with pointer to the resource load error.
690 void EwkViewImpl::informResourceLoadFailed(Ewk_Resource* resource, Ewk_Error* error)
692 Ewk_Resource_Load_Error resourceLoadError = {resource, error};
693 evas_object_smart_callback_call(m_view, "resource,request,failed", &resourceLoadError);
698 * Finished loading a resource in the view.
700 * Emits signal: "resource,request,finished" with pointer to the resource.
702 void EwkViewImpl::informResourceLoadFinished(Ewk_Resource* resource)
704 evas_object_smart_callback_call(m_view, "resource,request,finished", resource);
709 * Request was sent for a resource in the view.
711 * Emits signal: "resource,request,sent" with pointer to resource request and possible redirect response.
713 void EwkViewImpl::informResourceRequestSent(Ewk_Resource* resource, Ewk_Url_Request* request, Ewk_Url_Response* redirectResponse)
715 Ewk_Resource_Request resourceRequest = {resource, request, redirectResponse};
716 evas_object_smart_callback_call(m_view, "resource,request,sent", &resourceRequest);
721 * The view title was changed by the frame loader.
723 * Emits signal: "title,changed" with pointer to new title string.
725 void EwkViewImpl::informTitleChange(const String& title)
727 evas_object_smart_callback_call(m_view, "title,changed", const_cast<char*>(title.utf8().data()));
733 void EwkViewImpl::informTooltipTextChange(const String& text)
736 evas_object_smart_callback_call(m_view, "tooltip,text,unset", 0);
738 evas_object_smart_callback_call(m_view, "tooltip,text,set", const_cast<char*>(text.utf8().data()));
744 * informs that the requested text was found.
746 * Emits signal: "text,found" with the number of matches.
748 void EwkViewImpl::informTextFound(unsigned matchCount)
750 evas_object_smart_callback_call(m_view, "text,found", &matchCount);
753 IntSize EwkViewImpl::size() const
756 evas_object_geometry_get(m_view, 0, 0, &width, &height);
757 return IntSize(width, height);
760 bool EwkViewImpl::isFocused() const
762 return evas_object_focus_get(m_view);
765 bool EwkViewImpl::isVisible() const
767 return evas_object_visible_get(m_view);
770 const char* EwkViewImpl::title() const
772 m_title = pageProxy->pageTitle().utf8().data();
779 * This function may return @c NULL.
781 InputMethodContextEfl* EwkViewImpl::inputMethodContext()
783 return m_inputMethodContext.get();
786 const char* EwkViewImpl::themePath() const
791 void EwkViewImpl::setThemePath(const char* theme)
793 if (m_theme != theme) {
795 pageProxy->setThemePath(theme);
799 const char* EwkViewImpl::customTextEncodingName() const
801 String customEncoding = pageProxy->customTextEncodingName();
802 if (customEncoding.isEmpty())
805 m_customEncoding = customEncoding.utf8().data();
807 return m_customEncoding;
810 void EwkViewImpl::setCustomTextEncodingName(const char* encoding)
812 m_customEncoding = encoding;
813 pageProxy->setCustomTextEncodingName(encoding ? encoding : String());
816 void EwkViewImpl::setMouseEventsEnabled(bool enabled)
818 if (m_mouseEventsEnabled == enabled)
821 m_mouseEventsEnabled = enabled;
823 Ewk_View_Smart_Data* sd = smartData();
824 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown, sd);
825 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp, sd);
826 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove, sd);
828 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onMouseDown);
829 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onMouseUp);
830 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onMouseMove);
834 #if ENABLE(TOUCH_EVENTS)
835 void EwkViewImpl::setTouchEventsEnabled(bool enabled)
837 if (m_touchEventsEnabled == enabled)
840 m_touchEventsEnabled = enabled;
843 // FIXME: We have to connect touch callbacks with mouse and multi events
844 // because the Evas creates mouse events for first touch and multi events
845 // for second and third touches. Below codes should be fixed when the Evas
846 // supports the touch events.
847 // See https://bugs.webkit.org/show_bug.cgi?id=97785 for details.
848 Ewk_View_Smart_Data* sd = smartData();
849 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown, sd);
850 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp, sd);
851 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove, sd);
852 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown, sd);
853 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp, sd);
854 evas_object_event_callback_add(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove, sd);
856 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_DOWN, onTouchDown);
857 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_UP, onTouchUp);
858 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MOUSE_MOVE, onTouchMove);
859 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_DOWN, onTouchDown);
860 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_UP, onTouchUp);
861 evas_object_event_callback_del(m_view, EVAS_CALLBACK_MULTI_MOVE, onTouchMove);
868 * Update the view's favicon and emits a "icon,changed" signal if it has
871 * This function is called whenever the URL has changed or when the icon for
872 * the current page URL has changed.
874 void EwkViewImpl::informIconChange()
876 #if ENABLE(TIZEN_ICON_DATABASE)
879 Ewk_Favicon_Database* iconDatabase = context->faviconDatabase();
880 ASSERT(iconDatabase);
882 m_faviconURL = ewk_favicon_database_icon_url_get(iconDatabase, m_url);
883 evas_object_smart_callback_call(m_view, "icon,changed", 0);
886 #if ENABLE(WEB_INTENTS)
889 * The view received a new intent request.
891 * Emits signal: "intent,request,new" with pointer to a Ewk_Intent.
893 void EwkViewImpl::informIntentRequest(Ewk_Intent* ewkIntent)
895 evas_object_smart_callback_call(m_view, "intent,request,new", ewkIntent);
899 #if ENABLE(WEB_INTENTS_TAG)
902 * The view received a new intent service registration.
904 * Emits signal: "intent,service,register" with pointer to a Ewk_Intent_Service.
906 void EwkViewImpl::informIntentServiceRegistration(Ewk_Intent_Service* ewkIntentService)
908 evas_object_smart_callback_call(m_view, "intent,service,register", ewkIntentService);
910 #endif // ENABLE(WEB_INTENTS_TAG)
912 #if USE(ACCELERATED_COMPOSITING)
913 bool EwkViewImpl::createGLSurface(const IntSize& viewSize)
915 Ewk_View_Smart_Data* sd = smartData();
917 Evas_GL_Config evasGlConfig = {
920 EVAS_GL_STENCIL_NONE,
921 EVAS_GL_OPTIONS_NONE,
922 EVAS_GL_MULTISAMPLE_NONE
925 ASSERT(!evasGlSurface);
926 evasGlSurface = evas_gl_surface_create(evasGl, &evasGlConfig, viewSize.width(), viewSize.height());
930 Evas_Native_Surface nativeSurface;
931 evas_gl_native_surface_get(evasGl, evasGlSurface, &nativeSurface);
932 evas_object_image_native_surface_set(sd->image, &nativeSurface);
937 bool EwkViewImpl::enterAcceleratedCompositingMode()
940 EINA_LOG_DOM_WARN(_ewk_log_dom, "Accelerated compositing mode already entered.");
944 Evas* evas = evas_object_evas_get(m_view);
945 evasGl = evas_gl_new(evas);
949 evasGlContext = evas_gl_context_create(evasGl, 0);
950 if (!evasGlContext) {
951 evas_gl_free(evasGl);
956 if (!createGLSurface(size())) {
957 evas_gl_context_destroy(evasGl, evasGlContext);
960 evas_gl_free(evasGl);
965 #if ENABLE(WAIT_UPVERSION)
966 pageViewportControllerClient->setRendererActive(true);
971 bool EwkViewImpl::exitAcceleratedCompositingMode()
973 EINA_SAFETY_ON_NULL_RETURN_VAL(evasGl, false);
976 evas_gl_surface_destroy(evasGl, evasGlSurface);
981 evas_gl_context_destroy(evasGl, evasGlContext);
985 evas_gl_free(evasGl);
992 #if ENABLE(INPUT_TYPE_COLOR)
995 * Requests to show external color picker.
997 void EwkViewImpl::requestColorPicker(int r, int g, int b, int a, WKColorPickerResultListenerRef listener)
999 Ewk_View_Smart_Data* sd = smartData();
1000 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_request);
1002 m_colorPickerResultListener = listener;
1004 sd->api->input_picker_color_request(sd, r, g, b, a);
1009 * Requests to hide external color picker.
1011 void EwkViewImpl::dismissColorPicker()
1013 Ewk_View_Smart_Data* sd = smartData();
1014 EINA_SAFETY_ON_NULL_RETURN(sd->api->input_picker_color_dismiss);
1016 m_colorPickerResultListener.clear();
1018 sd->api->input_picker_color_dismiss(sd);
1024 * informs that the view's back / forward list has changed.
1026 * Emits signal: "back,forward,list,changed".
1028 void EwkViewImpl::informBackForwardListChange()
1030 evas_object_smart_callback_call(m_view, "back,forward,list,changed", 0);
1035 * Web process has crashed.
1037 * Emits signal: "webprocess,crashed" with pointer to crash handling boolean.
1039 void EwkViewImpl::informWebProcessCrashed()
1041 bool handled = false;
1042 evas_object_smart_callback_call(m_view, "webprocess,crashed", &handled);
1045 CString url = pageProxy->urlAtProcessExit().utf8();
1046 WARN("WARNING: The web process experienced a crash on '%s'.\n", url.data());
1048 // Display an error page
1049 ewk_view_html_string_load(m_view, "The web process has crashed.", 0, url.data());
1053 void EwkViewImpl::informContentsSizeChange(const IntSize& size)
1055 #if USE(COORDINATED_GRAPHICS)
1056 pageViewportControllerClient->didChangeContentsSize(size);
1062 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_RIGHT_TO_LEFT, RTL);
1063 COMPILE_ASSERT_MATCHING_ENUM(EWK_TEXT_DIRECTION_LEFT_TO_RIGHT, LTR);
1065 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1066 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex, bool multiple)
1068 void EwkViewImpl::requestPopupMenu(WebPopupMenuProxyEfl* popupMenu, const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, int32_t selectedIndex)
1071 Ewk_View_Smart_Data* sd = smartData();
1076 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1077 if (multiple ? !sd->api->multiple_popup_menu_show : !sd->api->popup_menu_show)
1079 if (!sd->api->popup_menu_show)
1084 ewk_view_popup_menu_close(m_view);
1085 popupMenuProxy = popupMenu;
1087 Eina_List* popupItems = 0;
1088 const size_t size = items.size();
1089 for (size_t i = 0; i < size; ++i)
1090 popupItems = eina_list_append(popupItems, Ewk_Popup_Menu_Item::create(items[i]).leakPtr());
1091 popupMenuItems = popupItems;
1093 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1094 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1095 if (multiple ? sd->api->multiple_popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems)
1096 : sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1098 if (sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupMenuItems, selectedIndex)) {
1100 /* maps.google.com generate mouse event in touch down without preventDefault.
1101 * So, popup menu is opend in touch down event and closed via fake mouse down
1102 * which generated by endTap.
1103 * In order to fix select of maps.google.com (based on touch behavior),
1104 * We should disable touch events when select popup is open.
1107 #if ENABLE(TIZEN_GESTURE)
1108 gestureClient->reset();
1110 ewk_view_touch_events_enabled_set(m_view, false);
1113 sd->api->popup_menu_show(sd, rect, static_cast<Ewk_Text_Direction>(textDirection), pageScaleFactor, popupItems, selectedIndex);
1119 * Calls a smart member function for javascript alert().
1121 void EwkViewImpl::requestJSAlertPopup(const WKEinaSharedString& message)
1123 Ewk_View_Smart_Data* sd = smartData();
1126 if (!sd->api->run_javascript_alert)
1129 sd->api->run_javascript_alert(sd, message);
1134 * Calls a smart member function for javascript confirm() and returns a value from the function. Returns false by default.
1136 bool EwkViewImpl::requestJSConfirmPopup(const WKEinaSharedString& message)
1138 Ewk_View_Smart_Data* sd = smartData();
1141 if (!sd->api->run_javascript_confirm)
1144 return sd->api->run_javascript_confirm(sd, message);
1149 * Calls a smart member function for javascript prompt() and returns a value from the function. Returns null string by default.
1151 WKEinaSharedString EwkViewImpl::requestJSPromptPopup(const WKEinaSharedString& message, const WKEinaSharedString& defaultValue)
1153 Ewk_View_Smart_Data* sd = smartData();
1156 if (!sd->api->run_javascript_prompt)
1157 return WKEinaSharedString();
1159 return WKEinaSharedString::adopt(sd->api->run_javascript_prompt(sd, message, defaultValue));
1162 #if ENABLE(SQL_DATABASE)
1165 * Calls exceeded_database_quota callback or falls back to default behavior returns default database quota.
1167 unsigned long long EwkViewImpl::informDatabaseQuotaReached(const String& databaseName, const String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage)
1169 Ewk_View_Smart_Data* sd = smartData();
1172 static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
1173 if (sd->api->exceeded_database_quota)
1174 return sd->api->exceeded_database_quota(sd, databaseName.utf8().data(), displayName.utf8().data(), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
1176 return defaultQuota;
1182 * The url of view was changed by the frame loader.
1184 * Emits signal: "url,changed" with pointer to new url string.
1186 void EwkViewImpl::informURLChange()
1188 String activeURL = pageProxy->activeURL();
1189 if (activeURL.isEmpty())
1192 CString rawActiveURL = activeURL.utf8();
1193 if (m_url == rawActiveURL.data())
1196 m_url = rawActiveURL.data();
1197 const char* callbackArgument = static_cast<const char*>(m_url);
1198 evas_object_smart_callback_call(m_view, "url,changed", const_cast<char*>(callbackArgument));
1200 evas_object_smart_callback_call(m_view, "uri,changed", const_cast<char*>(callbackArgument));
1203 // Update the view's favicon.
1207 WKPageRef EwkViewImpl::createNewPage()
1209 Evas_Object* newEwkView = 0;
1210 evas_object_smart_callback_call(m_view, "create,window", &newEwkView);
1215 EwkViewImpl* newViewImpl = EwkViewImpl::fromEvasObject(newEwkView);
1216 ASSERT(newViewImpl);
1218 return static_cast<WKPageRef>(WKRetain(newViewImpl->page()));
1221 void EwkViewImpl::closePage()
1223 evas_object_smart_callback_call(m_view, "close,window", 0);
1226 void EwkViewImpl::onMouseDown(void* data, Evas*, Evas_Object*, void* eventInfo)
1228 Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
1229 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1230 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1231 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down);
1232 sd->api->mouse_down(sd, downEvent);
1235 void EwkViewImpl::onMouseUp(void* data, Evas*, Evas_Object*, void* eventInfo)
1237 Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
1238 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1239 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1240 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up);
1241 sd->api->mouse_up(sd, upEvent);
1244 void EwkViewImpl::onMouseMove(void* data, Evas*, Evas_Object*, void* eventInfo)
1246 Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
1247 Ewk_View_Smart_Data* sd = static_cast<Ewk_View_Smart_Data*>(data);
1248 EINA_SAFETY_ON_NULL_RETURN(sd->api);
1249 EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move);
1250 sd->api->mouse_move(sd, moveEvent);
1253 #if ENABLE(TOUCH_EVENTS)
1254 void EwkViewImpl::feedTouchEvents(Ewk_Touch_Event_Type type)
1256 Ewk_View_Smart_Data* sd = smartData();
1258 unsigned count = evas_touch_point_list_count(sd->base.evas);
1262 Eina_List* points = 0;
1263 for (unsigned i = 0; i < count; ++i) {
1264 Ewk_Touch_Point* point = new Ewk_Touch_Point;
1265 point->id = evas_touch_point_list_nth_id_get(sd->base.evas, i);
1266 evas_touch_point_list_nth_xy_get(sd->base.evas, i, &point->x, &point->y);
1267 point->state = evas_touch_point_list_nth_state_get(sd->base.evas, i);
1268 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
1269 if (type == EWK_TOUCH_CANCEL)
1270 point->state = EVAS_TOUCH_POINT_CANCEL;
1272 points = eina_list_append(points, point);
1275 ewk_view_feed_touch_event(m_view, type, points, evas_key_modifier_get(sd->base.evas));
1278 EINA_LIST_FREE(points, data)
1279 delete static_cast<Ewk_Touch_Point*>(data);
1282 void EwkViewImpl::onTouchDown(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1284 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1285 viewImpl->feedTouchEvents(EWK_TOUCH_START);
1288 void EwkViewImpl::onTouchUp(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1290 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1291 viewImpl->feedTouchEvents(EWK_TOUCH_END);
1294 void EwkViewImpl::onTouchMove(void* /* data */, Evas* /* canvas */, Evas_Object* ewkView, void* /* eventInfo */)
1296 EwkViewImpl* viewImpl = EwkViewImpl::fromEvasObject(ewkView);
1297 viewImpl->feedTouchEvents(EWK_TOUCH_MOVE);
1302 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1303 AffineTransform EwkViewImpl::transformFromView() const
1305 AffineTransform transform;
1306 transform.scale(1 / m_scaleFactor);
1307 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1312 AffineTransform EwkViewImpl::transformToView() const
1314 return transformFromView().inverse();
1318 AffineTransform EwkViewImpl::transformFromScene() const
1320 AffineTransform transform;
1322 #if USE(TILED_BACKING_STORE)
1323 // FIXME: We have to scale firstly unlike open source, because we are using scaled scroll position.
1324 //transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1325 //transform.scale(1 / m_scaleFactor);
1326 transform.scale(1 / m_scaleFactor);
1327 transform.translate(m_scrollPosition.x(), m_scrollPosition.y());
1330 Ewk_View_Smart_Data* sd = smartData();
1331 transform.translate(-sd->view.x, -sd->view.y);
1336 AffineTransform EwkViewImpl::transformToScene() const
1338 return transformFromScene().inverse();
1341 AffineTransform EwkViewImpl::transformToScreen() const
1343 AffineTransform transform;
1345 int windowGlobalX = 0;
1346 int windowGlobalY = 0;
1348 Ewk_View_Smart_Data* sd = smartData();
1351 Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(sd->base.evas);
1352 Ecore_X_Window window = ecore_evas_software_x11_window_get(ecoreEvas); // Returns 0 if none.
1354 int x, y; // x, y are relative to parent (in a reparenting window manager).
1356 ecore_x_window_geometry_get(window, &x, &y, 0, 0);
1359 window = ecore_x_window_parent_get(window);
1363 transform.translate(-sd->view.x, -sd->view.y);
1364 transform.translate(windowGlobalX, windowGlobalY);
1369 #if ENABLE(TIZEN_WEBKIT2_SEPERATE_LOAD_PROGRESS)
1370 void EwkViewImpl::informLoadProgressStarted()
1372 evas_object_smart_callback_call(m_view, "load,progress,started", 0);
1375 void EwkViewImpl::informLoadProgressFinished()
1377 evas_object_smart_callback_call(m_view, "load,progress,finished", 0);
1381 #if ENABLE(TIZEN_DATALIST_ELEMENT)
1382 void EwkViewImpl::deleteDataList()
1384 EINA_SAFETY_ON_NULL_RETURN(dataList);
1387 EINA_LIST_FREE(dataList, item)
1388 eina_stringshare_del(static_cast<char*>(item));
1394 #if ENABLE(TIZEN_GESTURE)
1395 #if ENABLE(TOUCH_EVENTS)
1396 void EwkViewImpl::feedTouchEventsByType(Ewk_Touch_Event_Type type)
1398 feedTouchEvents(type);
1402 void EwkViewImpl::setDoubleTapEnabled(bool enabled)
1404 gestureRecognizer->setDoubleTapEnabled(enabled);
1408 #endif //#if OS(TIZEN)