4cc6b2023762d4258a75ab227fa34deb52d1bbed
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / API / efl / PageClientImpl.cpp
1 /*
2  * Copyright (C) 2011 Samsung Electronics
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "PageClientImpl.h"
28
29 #include "EwkViewImpl.h"
30 #include "InputMethodContextEfl.h"
31 #include "NativeWebKeyboardEvent.h"
32 #include "NotImplemented.h"
33 #include "TransformationMatrix.h"
34 #include "WebContext.h"
35 #include "WebContextMenuProxy.h"
36 #include "WebPageProxy.h"
37 #include "WebPopupMenuProxyEfl.h"
38 #include "ewk_context.h"
39 #include "ewk_context_private.h"
40 #include "ewk_download_job.h"
41 #include "ewk_download_job_private.h"
42 #include "ewk_view.h"
43
44 #if OS(TIZEN)
45 #include "DrawingAreaProxyImpl.h"
46 #include "Editor.h"
47 #include "EflScreenUtilities.h"
48 #include "LayerTreeCoordinatorProxy.h"
49 #include "OpenGLShims.h"
50 #include "WebContextMenuProxyTizen.h"
51 #include "WebLayerTreeRenderer.h"
52 #include "WebPageGroup.h"
53 #include "WebPageMessages.h"
54 #include "WebPopupMenuProxyEfl.h"
55 #include "WebPreferences.h"
56 #include "ewk_view.h"
57 #include <Ecore_Evas.h>
58 #include <Ecore_X.h>
59
60 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
61 #include "MainFrameScrollbarTizen.h"
62 #endif
63
64 #if ENABLE(TIZEN_WEBKIT2_CLIPBOARD_HELPER)
65 #include "ClipboardHelper.h"
66 #endif
67
68 #if ENABLE(TIZEN_DRAG_SUPPORT)
69 #include "DragData.h"
70 #endif
71 #endif
72
73 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
74 #include "ewk_context_private.h"
75 #endif
76
77 #if ENABLE(TIZEN_SCREEN_READER)
78 #include "ScreenReaderProxy.h"
79 #endif
80
81 using namespace WebCore;
82 using namespace std;
83
84 namespace WebKit {
85
86 PageClientImpl::PageClientImpl(EwkViewImpl* viewImpl)
87     : m_viewImpl(viewImpl)
88 #if OS(TIZEN)
89     , m_viewportConstraints()
90     , m_viewFocused(false)
91     , m_viewWindowActive(true)
92     , m_pageDidRendered(true)
93     , m_viewportAngle(0)
94     , m_viewportFitsToContent(false)
95 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
96     , m_visibleContentRect(IntRect())
97     , m_scaleFactor(0)
98     , m_hasSuspendedContent(false)
99 #endif
100 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
101     , m_restoredScaleFactor(0)
102 #endif
103     , m_isVisible(true)
104     , m_isScrollableLayerFocused(false)
105     , m_isScrollableNodeFocused(false)
106 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
107     , m_shouldMakeBackupTexture(false)
108     , m_shouldShowBackupTexture(false)
109 #endif
110 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
111     , m_isContextMenuVisible(false)
112 #endif
113 #if ENABLE(TIZEN_PRERENDERING_FOR_ROTATION)
114     , m_waitFrameOfNewViewortSize(false)
115 #endif
116 #endif // #if OS(TIZEN)
117 {
118 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
119     setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
120     setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
121 #endif
122
123 #if OS(TIZEN)
124 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
125     m_textSelection = TextSelection::create(m_viewImpl);
126 #endif
127 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
128     m_offlinePageSave = OfflinePageSave::create(m_viewImpl);
129 #endif
130 #if ENABLE(TIZEN_WEBKIT2_CLIPBOARD_HELPER)
131     m_clipboardHelper = ClipboardHelper::create(m_viewImpl);
132 #endif
133 #if ENABLE(TIZEN_DRAG_SUPPORT)
134     m_drag = Drag::create(m_viewImpl);
135 #endif
136 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
137     m_formDataCandidate = FormDataCandidate::create(m_viewImpl);
138 #endif
139     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewImpl->view()));
140     m_viewportAngle = ecore_evas_rotation_get(ee);
141 #endif
142
143     setBackgroundColor(1, 1, 1, 1);
144 }
145
146 PageClientImpl::~PageClientImpl()
147 {
148     if (m_viewImpl && m_viewImpl->page())
149         m_viewImpl->page()->close();
150 }
151
152 #if OS(TIZEN)
153 PageClientImpl::ViewportConstraints PageClientImpl::computeViewportConstraints(const WebCore::ViewportAttributes& attributes)
154 {
155     PageClientImpl::ViewportConstraints constraints;
156     constraints.minimumScale = attributes.minimumScale * attributes.devicePixelRatio;
157     constraints.maximumScale = attributes.maximumScale * attributes.devicePixelRatio;
158     constraints.userScalable = attributes.userScalable;
159     constraints.layoutSize = attributes.layoutSize;
160     constraints.contentsDefinedInitialScale = (ViewportArguments::ValueAuto != attributes.initialScale);
161
162     bool autoFittingEnabled = m_viewImpl->page()->pageGroup()->preferences()->autoFittingEnabled();
163     if (autoFittingEnabled)
164         constraints.initialScale = attributes.minimumScale * attributes.devicePixelRatio;
165     else {
166         // if content doesn't set initial scale value, set readable scale factor
167         // if not, set initial scale factor of viewport attribute
168         if (attributes.initialScale == ViewportArguments::ValueAuto)
169             constraints.initialScale = m_viewImpl->page()->deviceScaleFactor();
170         else
171             constraints.initialScale = attributes.initialScale * attributes.devicePixelRatio;
172     }
173
174     // adjust scale with both minimum and maximum scale factor
175     constraints.initialScale = adjustScaleWithViewport(constraints.initialScale);
176
177     return constraints;
178 }
179
180 double PageClientImpl::adjustScaleWithViewport(double scale)
181 {
182     double minimumScale = min(m_viewportConstraints.minimumScale, m_viewportConstraints.maximumScale);
183     return clampTo(scale, minimumScale, m_viewportConstraints.maximumScale);
184 }
185
186 #if USE(TILED_BACKING_STORE) && ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
187 void PageClientImpl::updateViewportSize(const IntSize& viewportSize, const int angle)
188 {
189     // update viewport size of webkit
190     m_visibleContentRect.setSize(viewportSize);
191     m_visibleContentRect = adjustVisibleContentRect(m_visibleContentRect, m_scaleFactor);
192     m_viewImpl->setScrollPosition(m_visibleContentRect.location());
193     m_viewImpl->page()->setViewportSize(viewportSize);
194 }
195 #endif
196
197 void PageClientImpl::prepareRestoredVisibleContectRect()
198 {
199     m_restoredScaleFactor = scaleFactor();
200     m_restoredScrollPosition = scrollPosition();
201 }
202
203 void PageClientImpl::initializeVisibleContentRect()
204 {
205     _ewk_view_resume_painting(m_viewImpl->view());
206
207 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
208     IntPoint initialScrollPosition;
209     float initialScaleFactor = m_viewportConstraints.initialScale;
210 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
211     // if scroll position and scale factor are restored by history controller,
212     // move scroll position and scale factor with them
213     if (m_restoredScaleFactor) {
214         initialScrollPosition = m_restoredScrollPosition;
215         initialScaleFactor = m_restoredScaleFactor;
216     }
217 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
218     m_restoredScaleFactor = 0;
219 #endif
220 #endif
221     setVisibleContentRect(IntRect(initialScrollPosition, m_visibleContentRect.size()), initialScaleFactor);
222 #else
223     // Set initial scale.
224     m_viewImpl->page()->scalePage(m_viewportConstraints.initialScale, IntPoint(0, 0));
225 #endif
226 }
227
228 double PageClientImpl::availableMinimumScale()
229 {
230     // recalculate minimum scale factor if contents' width exceeds viewport layout width and userScalable is true.
231     // minimum scale factor shouldn't be smaller than 0.25(minimum zoom level)
232     IntSize contentsSize = m_viewImpl->page()->contentsSize();
233     double horizontalMinScale = max(((double)viewSize().width() / contentsSize.width()), 0.25);
234     double verticalMinScale = max(((double)viewSize().height() / contentsSize.height()), 0.25);
235     // If there's only a bit ignorable difference between horizontalMinScale and verticalMinScale,
236     // ignore verticalMinScale to fit content's width to view
237     const double ignorableThreshold = 0.01;
238     if (fabs(horizontalMinScale - verticalMinScale) < ignorableThreshold)
239         verticalMinScale = horizontalMinScale;
240     return min(max(horizontalMinScale, verticalMinScale), m_viewportConstraints.maximumScale);
241 }
242
243 void PageClientImpl::fitViewportToContent()
244 {
245     setVisibleContentRect(m_visibleContentRect, m_viewportConstraints.minimumScale);
246 }
247
248 void PageClientImpl::setFocusedNodeRect(const IntRect& focusedNodeRect)
249 {
250     m_focusedNodeRect = focusedNodeRect;
251 }
252
253 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
254 bool PageClientImpl::scrollBy(IntSize scrollOffset)
255 {
256 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
257     // scrollOffset means device screen coordiate, not an actual offset of contents.
258     // Therefore, scrollOffset should be nomalized in order to make a tiled backing store
259     // in the actual scale.
260     IntSize scaledScrollOffset = m_viewImpl->transformFromScene().mapSize(scrollOffset);
261     if ((m_isScrollableLayerFocused || m_isScrollableNodeFocused)
262         && m_viewImpl->page()->scrollOverflow(FloatPoint(scaledScrollOffset.width(), scaledScrollOffset.height()))) {
263         displayViewport();
264         return false;
265     }
266 #endif
267
268     IntPoint oldScrollPosition = scrollPosition();
269     setVisibleContentRect(IntRect(oldScrollPosition + scrollOffset, m_visibleContentRect.size()), scaleFactor(), FloatPoint(scrollOffset.width(), scrollOffset.height()));
270
271     return true;
272 }
273
274 void PageClientImpl::scrollTo(IntPoint requestedScrollPosition)
275 {
276     setVisibleContentRect(IntRect(requestedScrollPosition, m_visibleContentRect.size()), scaleFactor());
277 }
278 #endif // #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
279
280 #endif // #if OS(TIZEN)
281
282 EwkViewImpl* PageClientImpl::viewImpl() const
283 {
284     return m_viewImpl;
285 }
286
287 // PageClient
288 PassOwnPtr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy()
289 {
290     return DrawingAreaProxyImpl::create(m_viewImpl->page());
291 }
292
293 void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect)
294 {
295 #if OS(TIZEN)
296     ewk_view_mark_for_sync(m_viewImpl->view());
297 #else
298     m_viewImpl->redrawRegion(rect);
299 #endif
300
301 #if ENABLE(TIZEN_SCREEN_READER)
302     if (rect.intersects(ewkViewGetFocusRing(m_viewImpl->view())->rect()))
303         m_viewImpl->page()->recalcScreenReaderFocusRect();
304 #endif
305 }
306
307 void PageClientImpl::displayView()
308 {
309     notImplemented();
310 }
311
312 void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize&)
313 {
314     setViewNeedsDisplay(scrollRect);
315 }
316
317 WebCore::IntSize PageClientImpl::viewSize()
318 {
319     return m_viewImpl->size();
320 }
321
322 bool PageClientImpl::isViewVisible()
323 {
324 #if OS(TIZEN)
325     return m_isVisible;
326 #else
327     return m_viewImpl->isVisible();
328 #endif
329 }
330
331 bool PageClientImpl::isViewInWindow()
332 {
333     notImplemented();
334     return true;
335 }
336
337 void PageClientImpl::processDidCrash()
338 {
339     // Check if loading was ongoing, when web process crashed.
340     double loadProgress = ewk_view_load_progress_get(m_viewImpl->view());
341     if (loadProgress >= 0 && loadProgress < 1)
342         m_viewImpl->informLoadProgress(1);
343
344     m_viewImpl->informWebProcessCrashed();
345 }
346
347 void PageClientImpl::didRelaunchProcess()
348 {
349     const char* themePath = m_viewImpl->themePath();
350     if (themePath)
351         m_viewImpl->page()->setThemePath(themePath);
352 }
353
354 void PageClientImpl::pageClosed()
355 {
356     notImplemented();
357 }
358
359 void PageClientImpl::toolTipChanged(const String&, const String& newToolTip)
360 {
361     m_viewImpl->informTooltipTextChange(newToolTip);
362 }
363
364 void PageClientImpl::setCursor(const Cursor& cursor)
365 {
366     m_viewImpl->setCursor(cursor);
367 }
368
369 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
370 {
371     notImplemented();
372 }
373
374 void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes& attributes)
375 {
376     double scaleRatioBeforeRotation = m_scaleFactor / m_viewportConstraints.minimumScale;
377     m_viewportConstraints = computeViewportConstraints(attributes);
378
379     // Initially, m_scaleFactor is not decided yet.
380     // So, we should update visible content rect at here.
381     if (!m_scaleFactor) {
382         setVisibleContentRect(m_visibleContentRect, m_viewportConstraints.initialScale);
383         return;
384     }
385
386     // if content is reloaded, contents size will not be changed
387     // so, we need to calculate minimum scale here.
388     // if content size is changed later, minimum scale will be re-calculated on didChangeContentsSize()
389     if (m_viewportConstraints.userScalable) {
390         if (fabs(m_viewportConstraints.initialScale - m_viewportConstraints.minimumScale) < numeric_limits<float>::epsilon())
391             m_viewportConstraints.initialScale = availableMinimumScale();
392         m_viewportConstraints.minimumScale = availableMinimumScale();
393     }
394
395     // setVisibleContentRect() should be called to adjust visible content rect only when view is resized
396     if (!m_pageDidRendered || m_viewImpl->page()->estimatedProgress() <= 0.1)
397         return;
398
399     // if IME is opened, visible content rect will be updated by ewk_view_focused_node_adjust()
400     if (ewk_view_focused_node_adjust(m_viewImpl->view()))
401         return;
402
403     float newScale = scaleFactor();
404     IntPoint newScrollPosition = m_visibleContentRect.location();
405     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewImpl->view()));
406     int angle = ecore_evas_rotation_get(ee);
407     bool isRotated = (angle != m_viewportAngle);
408
409     // if it's rotated, we need to fit content to viewport by minimize the scale
410     if (isRotated) {
411         m_viewportAngle = angle;
412         newScale = m_viewportConstraints.minimumScale * scaleRatioBeforeRotation;
413         newScrollPosition.scale(newScale / m_scaleFactor, newScale / m_scaleFactor);
414     }
415
416 #if ENABLE(TIZEN_PRERENDERING_FOR_ROTATION)
417     if (m_waitFrameOfNewViewortSize)
418         ewk_view_resume(m_viewImpl->view());
419 #endif
420
421 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
422     setVisibleContentRect(IntRect(newScrollPosition, m_visibleContentRect.size()), newScale);
423 #else
424     m_viewImpl->page()->scalePage(newScale, newScrollPosition);
425 #endif
426
427 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
428     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_viewImpl->view()));
429     if (smartData->api->formdata_candidate_is_showing(smartData))
430         smartData->api->formdata_candidate_hide(smartData);
431 #endif
432
433 #if ENABLE(TIZEN_FULLSCREEN_API)
434     if (m_viewImpl->page()->fullScreenManager()->isFullScreen())
435         m_viewImpl->page()->fullScreenManager()->updateMediaControlsStyle();
436 #endif
437 }
438
439 #if OS(TIZEN)
440 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
441 {
442     if (undoOrRedo == WebPageProxy::Undo) {
443         m_undoCommands.append(command);
444
445         int undoSize = m_undoCommands.size();
446         evas_object_smart_callback_call(m_viewImpl->view(), "undo,size", &undoSize);
447     }
448     else {
449         m_redoCommands.append(command);
450
451         int redoSize = m_redoCommands.size();
452         evas_object_smart_callback_call(m_viewImpl->view(), "redo,size", &redoSize);
453     }
454 }
455
456 void PageClientImpl::clearAllEditCommands()
457 {
458     m_undoCommands.clear();
459     m_redoCommands.clear();
460
461     int undoSize = m_undoCommands.size();
462     evas_object_smart_callback_call(m_viewImpl->view(), "undo,size", &undoSize);
463
464     int redoSize = m_redoCommands.size();
465     evas_object_smart_callback_call(m_viewImpl->view(), "redo,size", &redoSize);
466 }
467
468 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
469 {
470     if (undoOrRedo == WebPageProxy::Undo)
471         return !m_undoCommands.isEmpty();
472     else
473         return !m_redoCommands.isEmpty();
474 }
475
476 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
477 {
478     if (undoOrRedo == WebPageProxy::Undo) {
479         m_undoCommands.last()->unapply();
480         m_undoCommands.removeLast();
481
482         int undoSize = m_undoCommands.size();
483         evas_object_smart_callback_call(m_viewImpl->view(), "undo,size", &undoSize);
484     } else {
485         m_redoCommands.last()->reapply();
486         m_redoCommands.removeLast();
487
488         int redoSize = m_redoCommands.size();
489         evas_object_smart_callback_call(m_viewImpl->view(), "redo,size", &redoSize);
490     }
491 }
492 #else
493 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo)
494 {
495     notImplemented();
496 }
497
498 void PageClientImpl::clearAllEditCommands()
499 {
500     notImplemented();
501 }
502
503 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo)
504 {
505     notImplemented();
506     return false;
507 }
508
509 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo)
510 {
511     notImplemented();
512 }
513 #endif
514
515 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& viewRect)
516 {
517     notImplemented();
518     return viewRect;
519 }
520
521 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect)
522 {
523     notImplemented();
524     return viewRect;
525 }
526
527 IntPoint PageClientImpl::screenToWindow(const IntPoint& point)
528 {
529     notImplemented();
530     return point;
531 }
532
533 IntRect PageClientImpl::windowToScreen(const IntRect&)
534 {
535     notImplemented();
536     return IntRect();
537 }
538
539 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
540 {
541     notImplemented();
542 }
543
544 #if ENABLE(GESTURE_EVENTS)
545 void PageClientImpl::doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled)
546 {
547     notImplemented();
548 }
549 #endif
550
551 #if ENABLE(TOUCH_EVENTS)
552 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
553 {
554 #if OS(TIZEN)
555     ewk_view_touch_event_handler_result_set(m_viewImpl->view(), event.type(), wasEventHandled);
556 #else
557     notImplemented();
558 #endif // #if OS(TIZEN)
559 }
560 #endif
561
562 PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page)
563 {
564     return WebPopupMenuProxyEfl::create(m_viewImpl, page);
565 }
566
567 PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page)
568 {
569 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
570     return WebContextMenuProxyTizen::create(m_viewImpl->view(), page, this);
571 #else
572     notImplemented();
573     return 0;
574 #endif
575 }
576
577 #if ENABLE(INPUT_TYPE_COLOR)
578 PassRefPtr<WebColorChooserProxy> PageClientImpl::createColorChooserProxy(WebPageProxy*, const WebCore::Color&)
579 {
580     notImplemented();
581     return 0;
582 }
583 #endif
584
585 void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool, bool)
586 {
587     notImplemented();
588 }
589
590 #if !OS(TIZEN)
591 #if USE(ACCELERATED_COMPOSITING)
592 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&)
593 {
594     m_viewImpl->enterAcceleratedCompositingMode();
595 }
596
597 void PageClientImpl::exitAcceleratedCompositingMode()
598 {
599     m_viewImpl->exitAcceleratedCompositingMode();
600 }
601
602 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
603 {
604     notImplemented();
605 }
606 #endif // USE(ACCELERATED_COMPOSITING)
607 #endif
608
609 void PageClientImpl::initializeAcceleratedCompositingMode()
610 {
611 }
612
613 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
614 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
615 {
616     notImplemented();
617 }
618 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC)
619
620 void PageClientImpl::setBackgroundColor(double red, double green, double blue, double alpha)
621 {
622     WebCore::RGBA32 rgba= WebCore::makeRGBA32FromFloats((float)red, (float)green, (float)blue, (float)alpha);
623     m_bgColor.setRGB(rgba);
624 }
625
626 void PageClientImpl::didChangeScrollbarsForMainFrame() const
627 {
628     notImplemented();
629 }
630
631 #if OS(TIZEN)
632 void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
633 {
634 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
635     m_initialViewRect.setSize(viewSize());
636 #endif
637 }
638
639 void PageClientImpl::didChangeContentsSize(const WebCore::IntSize size)
640 {
641 #if USE(TILED_BACKING_STORE)
642     if (size.isEmpty())
643         return;
644
645 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
646     if (drawingArea()->layerTreeCoordinatorProxy())
647         drawingArea()->layerTreeCoordinatorProxy()->setContentsSize(WebCore::FloatSize(size.width(), size.height()));
648 #endif
649
650     // if minimum scale factor is changed, update minimumScale.
651     if (m_viewportConstraints.userScalable) {
652         double minimumScale = availableMinimumScale();
653
654         // Sometimes initializeVisibleContentRect can be called after content size change.
655         // So, if initialScale is not set explicitly in content's meta viewport tag and is same to minimumScale, update initialScale too.
656         if (!m_viewportConstraints.contentsDefinedInitialScale
657             && fabs(m_viewportConstraints.initialScale - m_viewportConstraints.minimumScale) < numeric_limits<float>::epsilon())
658             m_viewportConstraints.initialScale = minimumScale;
659         m_viewportConstraints.minimumScale = minimumScale;
660     }
661 #else
662     m_viewImpl->informContentsSizeChange(size);
663 #endif
664     if (!m_pageDidRendered || m_viewImpl->page()->estimatedProgress() <= 0.1)
665         return;
666
667     // FIXME: Do we really need to adjust visible content rect at here?
668     // if contents size is changed smaller and visible content rect is outside of content area,
669     // adjust visible content rect
670     bool needScrollAdjustment = (adjustVisibleContentRect(m_visibleContentRect, scaleFactor()) != m_visibleContentRect);
671     bool needScaleAdjustment = (fabs(adjustScaleWithViewport(scaleFactor()) - scaleFactor()) > numeric_limits<float>::epsilon());
672     if (needScrollAdjustment || needScaleAdjustment)
673         setVisibleContentRect(m_visibleContentRect, scaleFactor());
674 }
675
676 void PageClientImpl::pageScaleFactorDidChange()
677 {
678     ewk_view_focused_node_adjust(m_viewImpl->view());
679 }
680 #endif // #if OS(TIZEN)
681
682 void PageClientImpl::didCommitLoadForMainFrame(bool)
683 {
684 #if OS(TIZEN)
685     m_pageDidRendered = false;
686     m_viewportFitsToContent = false;
687     return;
688 #endif
689     notImplemented();
690 }
691
692 void PageClientImpl::didFinishLoadingDataForCustomRepresentation(const String&, const CoreIPC::DataReference&)
693 {
694     notImplemented();
695 }
696
697 double PageClientImpl::customRepresentationZoomFactor()
698 {
699     notImplemented();
700     return 0;
701 }
702
703 void PageClientImpl::setCustomRepresentationZoomFactor(double)
704 {
705     notImplemented();
706 }
707
708 void PageClientImpl::flashBackingStoreUpdates(const Vector<IntRect>&)
709 {
710     notImplemented();
711 }
712
713 void PageClientImpl::findStringInCustomRepresentation(const String&, FindOptions, unsigned)
714 {
715     notImplemented();
716 }
717
718 void PageClientImpl::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned)
719 {
720     notImplemented();
721 }
722
723 void PageClientImpl::updateTextInputState()
724 {
725 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
726     m_textSelection->update();
727     if (isTextSelectionMode() && isTextSelectionHandleDowned())
728         return;
729 #endif
730
731     InputMethodContextEfl* inputMethodContext = m_viewImpl->inputMethodContext();
732     if (inputMethodContext)
733         inputMethodContext->updateTextInputState();
734 }
735
736 void PageClientImpl::handleDownloadRequest(DownloadProxy* download)
737 {
738     Ewk_Context* context = m_viewImpl->ewkContext();
739     context->downloadManager()->registerDownload(download, m_viewImpl);
740 }
741
742 #if USE(TILED_BACKING_STORE)
743 void PageClientImpl::pageDidRequestScroll(const IntPoint& point)
744 {
745 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
746     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(m_viewImpl->view()));
747     if (smartData->api->formdata_candidate_is_showing(smartData))
748         return;
749 #endif
750 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
751     IntPoint newPoint = point;
752     newPoint.scale(scaleFactor(), scaleFactor());
753     setVisibleContentRect(IntRect(newPoint, m_visibleContentRect.size()), scaleFactor());
754 #endif
755 }
756 #endif
757
758 #if OS(TIZEN)
759 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
760 void PageClientImpl::pageDidRequestRestoreVisibleContentRect(const IntPoint& point, float scale)
761 {
762     m_restoredScrollPosition = point;
763     m_restoredScrollPosition.scale(scale, scale);
764     m_restoredScaleFactor = scale;
765
766     // Before contents size is fixed, just update visible content rect's position
767     m_visibleContentRect.setLocation(m_restoredScrollPosition);
768 }
769 #endif
770
771 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
772 void PageClientImpl::textChangeInTextField(const String& name, const String& value)
773 {
774     if (value == m_formDataCandidate->getCandidateValue()) {
775         m_formDataCandidate->updateCandidateValue(emptyString());
776         return;
777     }
778
779     m_formDataCandidate->updateCandidateValue(value);
780     ewk_view_text_change_in_textfield(m_viewImpl->view(), name, value);
781 }
782 #endif
783
784 void PageClientImpl::updateFormNavigation(int length, int offset)
785 {
786     notImplemented();
787 }
788
789 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
790 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
791 DrawingAreaProxy* PageClientImpl::drawingArea() const
792 {
793     return m_viewImpl->page()->drawingArea();
794 }
795 #endif
796
797 // Before rendering, scale factor and scroll position is different from m_viewImpl.
798 float PageClientImpl::scaleFactor()
799 {
800     return m_pageDidRendered ? m_viewImpl->scaleFactor() : (m_restoredScaleFactor ? m_restoredScaleFactor : m_viewportConstraints.initialScale);
801 }
802
803 const IntPoint PageClientImpl::scrollPosition()
804 {
805     return m_pageDidRendered ? m_viewImpl->scrollPosition() : (m_restoredScaleFactor ? m_restoredScrollPosition : IntPoint());
806 }
807
808 IntRect PageClientImpl::adjustVisibleContentRect(IntRect visibleContentRect, float targetScale)
809 {
810     IntSize contentsSize = m_viewImpl->page()->contentsSize();
811     contentsSize.scale(targetScale);
812     if (contentsSize.width() < visibleContentRect.width())
813         visibleContentRect.setX(0);
814     else
815         visibleContentRect.setX(clampTo(visibleContentRect.x(), 0, contentsSize.width() - visibleContentRect.width()));
816
817     if (contentsSize.height() < visibleContentRect.height())
818         visibleContentRect.setY(0);
819     else
820         visibleContentRect.setY(clampTo(visibleContentRect.y(), 0, contentsSize.height() - visibleContentRect.height()));
821     return visibleContentRect;
822 }
823
824 void PageClientImpl::setVisibleContentRect(const IntRect& newRect, float newScale, const FloatPoint& trajectory)
825 {
826 #if ENABLE(TIZEN_SCREEN_READER)
827     IntPoint previousScrollPosition(scrollPosition());
828     float previousScale = m_scaleFactor;
829 #endif
830
831     m_scaleFactor = adjustScaleWithViewport(newScale);
832     m_viewportFitsToContent = fabs(m_scaleFactor - m_viewportConstraints.minimumScale) < numeric_limits<float>::epsilon();
833     m_visibleContentRect.setLocation(newRect.location());
834     m_visibleContentRect = adjustVisibleContentRect(m_visibleContentRect, m_scaleFactor);
835
836     // update both drawing scale factor and scroll position after page is rendered
837     if (m_pageDidRendered) {
838         if (!m_hasSuspendedContent) {
839             // FIXME: We have to update EwkViewImpl's scale and position here because we use them to draw contents.
840             // PageViewport's values are updated when resuming content in the webkit opensource,
841             // but we have to update viewImpl's values here to sync with PageClient's values.
842             // However, We should not update them when hasSuspendedContent is true in order to maintain last values.
843             // The values will be updated when resuming content.
844             // Below codes should be refactored when PageViewportController codes are merged into Tizen.
845             m_viewImpl->setScaleFactor(m_scaleFactor);
846             m_viewImpl->setScrollPosition(m_visibleContentRect.location());
847         }
848     }
849
850     // enclosingIntRect produces inconsistent width and height when scale factor is not 1.
851     // So we removed enclosingIntRect and replaced with floorf and ceilf.
852     IntRect mapToContentsVisibleContentRect = IntRect(floorf(m_visibleContentRect.x() / m_scaleFactor),
853                                                       floorf(m_visibleContentRect.y() / m_scaleFactor),
854                                                       ceilf(m_visibleContentRect.width() / m_scaleFactor),
855                                                       ceilf(m_visibleContentRect.height() / m_scaleFactor));
856     if (!drawingArea())
857         return;
858     drawingArea()->setVisibleContentsRect(mapToContentsVisibleContentRect, m_scaleFactor, trajectory, FloatPoint(m_viewImpl->scrollPosition()));
859 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
860     // FIXME: We need to calculate exact visibleRect size here instead of mapToContentsVisibleContentRect.
861     drawingArea()->setVisibleContentsRectForScrollingContentsLayers(mapToContentsVisibleContentRect);
862 #endif
863     displayViewport();
864
865 #if ENABLE(TIZEN_SCREEN_READER)
866     if (ScreenReaderProxy::screenReader().isEnabled()
867         && (scrollPosition() != previousScrollPosition || m_scaleFactor != previousScale))
868         ewkViewGetFocusRing(m_viewImpl->view())->updateScrollAndScale(previousScrollPosition, previousScale);
869 #endif
870
871 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
872     if (!isClipboardWindowOpened())
873         updateTextSelectionHandlesAndContextMenu(true);
874 #endif
875 }
876
877 void PageClientImpl::displayViewport()
878 {
879     setViewNeedsDisplay(IntRect(IntPoint(), viewSize()));
880
881 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
882     updateScrollbar();
883 #endif
884
885 #if ENABLE(TIZEN_SCREEN_READER)
886     m_viewImpl->page()->recalcScreenReaderFocusRect();
887 #endif
888 }
889
890 void PageClientImpl::drawContents()
891 {
892 }
893
894 void PageClientImpl::drawContents(BackingStore::PlatformGraphicsContext context)
895 {
896     cairo_save(context);
897     const cairo_matrix_t matrix = cairo_matrix_t(m_viewImpl->transformToView());
898     cairo_transform(context, &matrix);
899
900     if (drawingArea()) {
901         if (drawingArea()->layerTreeCoordinatorProxy()) {
902             WebLayerTreeRenderer* renderer = drawingArea()->layerTreeCoordinatorProxy()->layerTreeRenderer();
903             renderer->paintToGraphicsContext(context, m_bgColor);
904         }
905     }
906
907     cairo_restore(context);
908 }
909
910 void PageClientImpl::scaleImage(double scaleFactor, IntPoint scrollPosition)
911 {
912 #if OS(TIZEN) && ENABLE(FULLSCREEN_API)
913     // We don't want to process scaling in the FullScreen mode.
914     if (m_viewImpl->page()->fullScreenManager()->isFullScreen())
915         return;
916 #endif
917
918 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
919     m_textSelection->hideHandlers();
920 #endif
921
922     // Adjust scaleFactor.
923 #if ENABLE(TIZEN_WEBKIT2_TEXT_ZOOM)
924     if (!m_viewImpl->page()->pageGroup()->preferences()->textZoomEnabled())
925         scaleFactor = adjustScaleWithViewport(scaleFactor);
926 #else
927     scaleFactor = adjustScaleWithViewport(scaleFactor);
928 #endif
929
930     scaleContents(scaleFactor, scrollPosition);
931 }
932
933 void PageClientImpl::scaleContents(double scaleFactor, const IntPoint& origin)
934 {
935 #if OS(TIZEN) && ENABLE(FULLSCREEN_API)
936     // We don't want to process scaling in the FullScreen mode.
937     if (m_viewImpl->page()->fullScreenManager()->isFullScreen())
938         return;
939 #endif
940     scaleFactor = adjustScaleWithViewport(scaleFactor);
941
942     setVisibleContentRect(IntRect(origin, m_visibleContentRect.size()), scaleFactor);
943 }
944
945 // FIXME: The concept of suspending content comes from webkit opensource's PageViewportController,
946 // so below code should be replaced when PageViewportController codes are merged.
947 // Please do not use below codes. They are only for scaling contents.
948 void PageClientImpl::suspendContent()
949 {
950     if (m_hasSuspendedContent)
951         return;
952
953     m_hasSuspendedContent = true;
954 }
955
956 void PageClientImpl::resumeContent()
957 {
958     if (!m_hasSuspendedContent)
959         return;
960
961     // FIXME: Update visibleContentRect with m_viewImpl after resuming content.
962     // The concept is that the values of EwkViewImpl and PageClient can be different
963     // during suspending content and they become same when content is resumed.
964     // Below codes should be refactored when PageViewportController codes are merged into Tizen.
965     setVisibleContentRect(IntRect(m_viewImpl->scrollPosition(), m_visibleContentRect.size()), m_viewImpl->scaleFactor());
966     m_hasSuspendedContent = false;
967 }
968
969 FloatPoint PageClientImpl::boundContentsPositionAtScale(const FloatPoint& framePosition, float scale)
970 {
971     // We need to floor the viewport here as to allow aligning the content in device units. If not,
972     // it might not be possible to scroll the last pixel and that affects fixed position elements.
973     FloatRect bounds;
974     const IntSize& contentsSize = m_viewImpl->page()->contentsSize();
975     bounds.setWidth(std::max(0.f, contentsSize.width() - floorf(viewSize().width() / scale)));
976     bounds.setHeight(std::max(0.f, contentsSize.height() - floorf(viewSize().height() / scale)));
977
978     FloatPoint position;
979     // Unfortunately it doesn't seem to be enough, so just always allow one pixel more.
980     position.setX(clampTo(framePosition.x(), bounds.x(), bounds.width() + 1));
981     position.setY(clampTo(framePosition.y(), bounds.y(), bounds.height() + 1));
982
983     return position;
984 }
985
986 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
987 void PageClientImpl::createScrollbarIfNeeded(bool horizontalBar, bool verticalBar)
988 {
989     // create if needed.
990     if (horizontalBar && !m_horizontalScrollbar) {
991         m_horizontalScrollbar = MainFrameScrollbarTizen::createNativeScrollbar(m_viewImpl->view(), HorizontalScrollbar);
992         IntRect hBarRect(0, viewSize().height(), viewSize().width(), 0);
993         m_horizontalScrollbar->setFrameRect(hBarRect);
994     } else if (!horizontalBar && m_horizontalScrollbar)
995         m_horizontalScrollbar = 0;
996
997     if (verticalBar && !m_verticalScrollbar) {
998         m_verticalScrollbar = MainFrameScrollbarTizen::createNativeScrollbar(m_viewImpl->view(), VerticalScrollbar);
999         IntRect vBarRect(viewSize().width(), 0, 0, viewSize().height());
1000         m_verticalScrollbar->setFrameRect(vBarRect);
1001     } else if (!verticalBar && m_verticalScrollbar)
1002         m_verticalScrollbar = 0;
1003 }
1004
1005 void PageClientImpl::updateScrollbar()
1006 {
1007     IntSize scaledContentsSize = m_viewImpl->page()->contentsSize();
1008     scaledContentsSize.scale(scaleFactor());
1009
1010     bool newHasHorizontalScrollbar = false;
1011     bool newVerticalScrollbar = false;
1012     if (viewSize().width() < scaledContentsSize.width())
1013         newHasHorizontalScrollbar = true;
1014     if (viewSize().height() < scaledContentsSize.height())
1015         newVerticalScrollbar = true;
1016     createScrollbarIfNeeded(newHasHorizontalScrollbar, newVerticalScrollbar);
1017
1018     if (m_horizontalScrollbar) {
1019         m_horizontalScrollbar->setProportion(viewSize().width(), scaledContentsSize.width());
1020         m_horizontalScrollbar->setPosition(m_viewImpl->scrollPosition().x());
1021     }
1022     if (m_verticalScrollbar) {
1023         m_verticalScrollbar->setProportion(viewSize().height(), scaledContentsSize.height());
1024         m_verticalScrollbar->setPosition(m_viewImpl->scrollPosition().y());
1025     }
1026 }
1027
1028 void PageClientImpl::frameRectChanged()
1029 {
1030     if (m_horizontalScrollbar) {
1031         IntRect hBarRect(0, viewSize().height(), viewSize().width(), 0);
1032         m_horizontalScrollbar->setFrameRect(hBarRect);
1033     }
1034     if (m_verticalScrollbar) {
1035         IntRect vBarRect(viewSize().width(), 0, 0, viewSize().height());
1036         m_verticalScrollbar->setFrameRect(vBarRect);
1037     }
1038 }
1039
1040 void PageClientImpl::updateVisibility()
1041 {
1042     if (m_horizontalScrollbar)
1043         m_horizontalScrollbar->updateVisibility();
1044     if (m_verticalScrollbar)
1045         m_verticalScrollbar->updateVisibility();
1046 }
1047 #endif
1048 #endif // ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1049
1050 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1051 bool PageClientImpl::isTextSelectionDowned()
1052 {
1053     return m_textSelection->isTextSelectionDowned();
1054 }
1055
1056 bool PageClientImpl::isTextSelectionMode()
1057 {
1058     return m_textSelection->isTextSelectionMode();
1059 }
1060
1061 void PageClientImpl::setIsTextSelectionMode(bool isTextSelectionMode)
1062 {
1063     m_textSelection->setIsTextSelectionMode(isTextSelectionMode);
1064 }
1065
1066 void PageClientImpl::updateTextSelectionHandlesAndContextMenu(bool isShow, bool isScrolling)
1067 {
1068     if (m_textSelection->isTextSelectionMode() && evas_object_focus_get(m_viewImpl->view()))
1069         m_textSelection->updateHandlesAndContextMenu(isShow, isScrolling);
1070 }
1071
1072 bool PageClientImpl::textSelectionDown(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside)
1073 {
1074     if (!evas_object_focus_get(m_viewImpl->view())) {
1075         InputMethodContextEfl* inputMethodContext = m_viewImpl->inputMethodContext();
1076         if (inputMethodContext)
1077             inputMethodContext->hideIMFContext();
1078
1079         evas_object_focus_set(m_viewImpl->view(), true);
1080     }
1081
1082     return m_textSelection->textSelectionDown(point, isStartedTextSelectionFromOutside);
1083 }
1084
1085 void PageClientImpl::textSelectionMove(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside)
1086 {
1087     m_textSelection->textSelectionMove(point, isStartedTextSelectionFromOutside);
1088 }
1089
1090 void PageClientImpl::textSelectionUp(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside)
1091 {
1092     m_textSelection->textSelectionUp(point, isStartedTextSelectionFromOutside);
1093 }
1094
1095 bool PageClientImpl::isTextSelectionHandleDowned()
1096 {
1097     return m_textSelection->isTextSelectionHandleDowned();
1098 }
1099
1100 #if ENABLE(TIZEN_WEBKIT2_FOR_MOVING_TEXT_SELECTION_HANDLE_FROM_OSP)
1101 void PageClientImpl::textSelectonHandleDown(const WebCore::IntPoint& point)
1102 {
1103     m_textSelection->textSelectionHandleDown(point);
1104 }
1105
1106 void PageClientImpl::textSelectonHandleMove(const WebCore::IntPoint& point)
1107 {
1108     m_textSelection->textSelectionHandleMove(point);
1109 }
1110
1111 void PageClientImpl::textSelectonHandleUp()
1112 {
1113     m_textSelection->textSelectionHandleUp();
1114 }
1115 #endif
1116
1117 void PageClientImpl::requestToShowTextSelectionHandlesAndContextMenu()
1118 {
1119     m_textSelection->requestToShow();
1120 }
1121
1122 void PageClientImpl::initTextSelectionHandlesMouseDownedStatus()
1123 {
1124     m_textSelection->initHandlesMouseDownedStatus();
1125 }
1126
1127 void PageClientImpl::changeContextMenuPosition(IntPoint& point)
1128 {
1129     m_textSelection->changeContextMenuPosition(point);
1130 }
1131 #endif
1132
1133 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
1134 void PageClientImpl::saveSerializedHTMLDataForMainPage(const String& serializedData, const String& fileName)
1135 {
1136     m_offlinePageSave->saveSerializedHTMLDataForMainPage(serializedData, fileName);
1137 }
1138
1139 void PageClientImpl::saveSubresourcesData(Vector<WebSubresourceTizen>& subresourceData)
1140 {
1141     m_offlinePageSave->saveSubresourcesData(subresourceData);
1142 }
1143
1144 void PageClientImpl::startOfflinePageSave(String& path, String& url, String& title)
1145 {
1146     m_offlinePageSave->startOfflinePageSave(path, url, title);
1147 }
1148 #endif
1149
1150 #if ENABLE(TIZEN_WEBKIT2_CLIPBOARD_HELPER)
1151 void PageClientImpl::pasteContextMenuSelected()
1152 {
1153     m_clipboardHelper->pasteClipboardLastItem(m_viewImpl->page()->editorState().isContentRichlyEditable);
1154 }
1155 #endif
1156
1157 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
1158 void PageClientImpl::setClipboardData(const String& data, const String& type)
1159 {
1160 #if ENABLE(TIZEN_WEBKIT2_CLIPBOARD_HELPER)
1161     m_clipboardHelper->setData(data, type);
1162 #endif
1163 }
1164
1165 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
1166 void PageClientImpl::clipboardContextMenuSelected()
1167 {
1168     m_clipboardHelper->openClipboardWindow(m_viewImpl->page()->editorState().isContentRichlyEditable);
1169 }
1170
1171 bool PageClientImpl::isClipboardWindowOpened()
1172 {
1173     return m_clipboardHelper->isClipboardWindowOpened();
1174 }
1175
1176 void PageClientImpl::closeClipboardWindow()
1177 {
1178     m_clipboardHelper->closeClipboardWindow();
1179 }
1180 #endif
1181
1182 void PageClientImpl::clearClipboardData()
1183 {
1184 #if ENABLE(TIZEN_WEBKIT2_CLIPBOARD_HELPER)
1185     m_clipboardHelper->clear();
1186 #endif
1187 }
1188 #endif
1189
1190 #if ENABLE(TIZEN_WEBKIT2_VIEW_VISIBILITY)
1191 void PageClientImpl::setIsVisible(bool isVisible)
1192 {
1193 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
1194     if (m_isVisible != isVisible && m_viewImpl->view() && m_pageDidRendered) {
1195         if (!isVisible && (drawingArea() && drawingArea()->layerTreeCoordinatorProxy()) && !m_shouldShowBackupTexture) {
1196             Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewImpl->view()));
1197             int angle = ecore_evas_rotation_get(ee);
1198             if (angle == 0 || angle == 180) {
1199                 m_shouldMakeBackupTexture = true;
1200                 m_shouldShowBackupTexture = true;
1201                 drawContents();
1202             }
1203         }
1204     }
1205 #endif
1206
1207     m_isVisible = isVisible;
1208
1209     WebPageProxy* pageProxy = m_viewImpl->page();
1210     if (pageProxy)
1211         pageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible);
1212
1213 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
1214     if (!m_isVisible)
1215         ewk_view_context_get(m_viewImpl->view())->clearAllDecodedData();
1216 #endif
1217 }
1218 #endif
1219
1220 #if ENABLE(TIZEN_DRAG_SUPPORT)
1221 void PageClientImpl::setDragPoint(const WebCore::IntPoint& point)
1222 {
1223     m_drag->setDragPoint(point);
1224 }
1225 bool PageClientImpl::isDragMode()
1226 {
1227     return m_drag->isDragMode();
1228 }
1229 void PageClientImpl::setDragMode(bool isDragMode)
1230 {
1231     m_drag->setDragMode(isDragMode);
1232 }
1233 void PageClientImpl::startDrag(const DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
1234 {
1235     DragData* dragInfo = new DragData(dragData.platformData(), m_drag->getDragPoint(),
1236         m_drag->getDragPoint(), dragData.draggingSourceOperationMask(), dragData.flags());
1237
1238     String dragStorageName("Drag");
1239     m_viewImpl->page()->dragEntered(dragInfo, dragStorageName);
1240     setDragMode(true);
1241     m_drag->setDragData(dragInfo);
1242     m_drag->Show();
1243 }
1244 #endif
1245
1246 #if ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
1247 bool PageClientImpl::isShowingFormDataCandidate()
1248 {
1249     return m_formDataCandidate->isShowing();
1250 }
1251
1252 void PageClientImpl::updateFormDataCandidate(const Vector<String>& data)
1253 {
1254     m_formDataCandidate->updateFormData(data);
1255 }
1256
1257 void PageClientImpl::hideFormDataCandidate()
1258 {
1259     m_formDataCandidate->hide();
1260 }
1261
1262 void PageClientImpl::showFormDataCandidate(const WebCore::IntRect& rect)
1263 {
1264     m_formDataCandidate->show(rect);
1265 }
1266 #endif
1267
1268 #if ENABLE(TIZEN_REGISTER_PROTOCOL_HANDLER)
1269 void PageClientImpl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
1270 {
1271     ewkViewRegisterProtocolHandlers(m_viewImpl->view(), scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data(), title.utf8().data());
1272 }
1273 #endif
1274
1275 #if ENABLE(TIZEN_CUSTOM_SCHEME_HANDLER)
1276 unsigned int PageClientImpl::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url)
1277 {
1278     return ewkViewIsProtocolHandlerRegistered(m_viewImpl->view(), scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data());
1279 }
1280
1281 void PageClientImpl::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url)
1282 {
1283     ewkViewUnregisterProtocolHandlers(m_viewImpl->view(), scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data());
1284 }
1285 #endif
1286
1287 #if ENABLE(TIZEN_REGISTER_CONTENT_HANDLER)
1288 void PageClientImpl::registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title)
1289 {
1290     ewkViewRegisterContentHandlers(m_viewImpl->view(), mimeType.utf8().data(), baseURL.utf8().data(), url.utf8().data(), title.utf8().data());
1291 }
1292
1293 unsigned int PageClientImpl::isContentHandlerRegistered(const String& mimeType, const String& baseURL, const String& url)
1294 {
1295     return ewkViewIsContentHandlerRegistered(m_viewImpl->view(), mimeType.utf8().data(), baseURL.utf8().data(), url.utf8().data());
1296 }
1297
1298 void PageClientImpl::unregisterContentHandler(const String& mimeType, const String& baseURL, const String& url)
1299 {
1300     ewkViewUnregisterContentHandlers(m_viewImpl->view(), mimeType.utf8().data(), baseURL.utf8().data(), url.utf8().data());
1301 }
1302 #endif
1303
1304 #if ENABLE(TIZEN_SEARCH_PROVIDER)
1305 void PageClientImpl::addSearchProvider(const String& baseURL, const String& engineURL)
1306 {
1307     ewkViewAddSearchProvider(m_viewImpl->view(), baseURL.utf8().data(), engineURL.utf8().data());
1308 }
1309
1310 unsigned long PageClientImpl::isSearchProviderInstalled(const String& baseURL, const String& engineURL)
1311 {
1312     return ewkViewIsSearchProviderInstalled(m_viewImpl->view(), baseURL.utf8().data(), engineURL.utf8().data());
1313 }
1314 #endif
1315
1316 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
1317 bool PageClientImpl::getStandaloneStatus()
1318 {
1319     return ewkViewGetStandaloneStatus(m_viewImpl->view());
1320 }
1321 #endif
1322
1323 #if ENABLE(SCREEN_ORIENTATION_SUPPORT) && ENABLE(TIZEN_SCREEN_ORIENTATION_SUPPORT)
1324 bool PageClientImpl::lockOrientation(int willLockOrientation)
1325 {
1326     return ewk_view_orientation_lock(m_viewImpl->view(), willLockOrientation);
1327 }
1328
1329 void PageClientImpl::unlockOrientation()
1330 {
1331     ewk_view_orientation_unlock(m_viewImpl->view());
1332 }
1333 #endif
1334
1335 void PageClientImpl::didRenderFrame()
1336 {
1337 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
1338     if (m_shouldShowBackupTexture && m_isVisible)
1339         m_shouldShowBackupTexture = false;
1340 #endif
1341     if (!m_pageDidRendered) {
1342         m_pageDidRendered = true;
1343         initializeVisibleContentRect();
1344     }
1345
1346 #if ENABLE(TIZEN_PRERENDERING_FOR_ROTATION)
1347     if (m_waitFrameOfNewViewortSize) {
1348         m_waitFrameOfNewViewortSize = false;
1349         ewkViewRotatePrepared(m_viewImpl->view());
1350     }
1351 #endif
1352 }
1353
1354 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1355 void PageClientImpl::setOverflowResult(bool pressed, WebLayerID webLayerID)
1356 {
1357     setIsScrollableLayerFocused(false);
1358     setIsScrollableNodeFocused(false);
1359
1360     if (pressed) {
1361         if (webLayerID) {
1362             setIsScrollableLayerFocused(true);
1363             m_viewImpl->page()->drawingArea()->layerTreeCoordinatorProxy()->layerTreeRenderer()->setFocusedLayerID(webLayerID);
1364         } else {
1365             setIsScrollableNodeFocused(true);
1366         }
1367     }
1368 }
1369
1370 void PageClientImpl::findScrollableNode(const IntPoint& point)
1371 {
1372     WebPageProxy* pageProxy = m_viewImpl->page();
1373     if (pageProxy && pageProxy->isLoadingFinished() && pageProxy->askOverflow()) {
1374         IntPoint pointForPress(m_viewImpl->transformFromScene().mapPoint(point));
1375         WebLayerID webLayerID = 0;
1376         bool checkOverflowLayer = false;
1377 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1378         DrawingAreaProxy* drawingArea = pageProxy->drawingArea();
1379         checkOverflowLayer = drawingArea && drawingArea->layerTreeCoordinatorProxy() && drawingArea->layerTreeCoordinatorProxy()->hasOverflowLayer();
1380 #endif
1381         setOverflowResult(pageProxy->setPressedNodeAtPoint(pointForPress, checkOverflowLayer, webLayerID), webLayerID);
1382     }
1383 }
1384 #endif
1385
1386 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1387 void PageClientImpl::didGetTextStyleStateForSelection(int underlineState, int italicState, int boldState)
1388 {
1389     WebCore::IntPoint startPoint, endPoint;
1390     WebCore::IntRect leftRect, rightRect;
1391
1392     WebCore::IntRect caretRect;
1393     m_viewImpl->page()->getCaretPosition(caretRect);
1394     if (!caretRect.isEmpty()) {
1395         startPoint.setX(caretRect.x());
1396         startPoint.setY(caretRect.y() + caretRect.height());
1397
1398         endPoint.setX(caretRect.x() + caretRect.width());
1399         endPoint.setY(caretRect.y() + caretRect.height());
1400     }
1401 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1402     else if (m_viewImpl->page()->getSelectionHandlers(leftRect, rightRect)) {
1403         startPoint.setX(leftRect.x());
1404         startPoint.setY(leftRect.y() + leftRect.height());
1405
1406         endPoint.setX(rightRect.x() + rightRect.width());
1407         endPoint.setY(rightRect.y() + rightRect.height());
1408     }
1409 #endif
1410
1411     startPoint.scale(scaleFactor(), scaleFactor());
1412     endPoint.scale(scaleFactor(), scaleFactor());
1413
1414     int viewPositionX, viewPositionY;
1415     evas_object_geometry_get(m_viewImpl->view(), &viewPositionX, &viewPositionY, NULL, NULL);
1416
1417     startPoint.move(-scrollPosition().x(),  -scrollPosition().y());
1418     startPoint.move(viewPositionX, viewPositionY);
1419
1420     endPoint.move(-scrollPosition().x(),  -scrollPosition().y());
1421     endPoint.move(viewPositionX, viewPositionY);
1422
1423     ewkViewDidGetTextStyleStateForSelection(m_viewImpl->view(), underlineState, italicState, boldState, startPoint, endPoint);
1424 }
1425 #endif
1426
1427 void PageClientImpl::didFindZoomableArea(const IntPoint& target, const IntRect& area)
1428 {
1429     ewk_view_zoomable_area_set(m_viewImpl->view(), target, area);
1430 }
1431
1432 #if ENABLE(TIZEN_ICON_DATABASE)
1433 void PageClientImpl::didReceiveIcon()
1434 {
1435     ewkViewIconReceived(m_viewImpl->view());
1436 }
1437 #endif
1438
1439 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
1440 void PageClientImpl::hideFocusRing()
1441 {
1442     ewkViewFocusRingHide(m_viewImpl->view());
1443 }
1444 #endif
1445 #endif // #if OS(TIZEN)
1446
1447
1448 #if ENABLE(TIZEN_WEBKIT2_TILED_AC) && ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
1449 PageClientEvasGL::PageClientEvasGL(EwkViewImpl* viewImpl)
1450     : PageClientImpl(viewImpl)
1451     , m_evasGL(0)
1452     , m_evasGlApi(0)
1453     , m_context(0)
1454     , m_surface(0)
1455     , m_config(0)
1456 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1457     , m_angle(0)
1458 #endif
1459     , m_isAcceleratedCompositingModeInitialized(false)
1460 {
1461     initializeAcceleratedCompositingMode();
1462 }
1463
1464 PageClientEvasGL::~PageClientEvasGL()
1465 {
1466     if (m_viewImpl && m_viewImpl->page())
1467         m_viewImpl->page()->close();
1468 }
1469
1470 void PageClientEvasGL::updateViewportSize(const WebCore::IntSize& viewportSize, const int angle)
1471 {
1472     if (m_surface) {
1473         evas_gl_surface_destroy(m_evasGL, m_surface);
1474         m_surface = 0;
1475     }
1476     setTargetSurface();
1477
1478     PageClientImpl::updateViewportSize(viewportSize, angle);
1479 }
1480
1481 void PageClientEvasGL::setViewNeedsDisplay(const WebCore::IntRect& rect)
1482 {
1483 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1484     if (!isDirectRendering())
1485 #endif
1486     drawContents();
1487     m_viewImpl->redrawRegion(rect);
1488
1489 #if ENABLE(TIZEN_SCREEN_READER)
1490     if (rect.intersects(ewkViewGetFocusRing(m_viewImpl->view())->rect()))
1491         m_viewImpl->page()->recalcScreenReaderFocusRect();
1492 #endif
1493 }
1494
1495 void PageClientEvasGL::displayViewport()
1496 {
1497 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1498     // We should not draw here when Direct Rendering is enabled.
1499     // Because we will draw directly when evas is updated - on_pixels_for_accelerated_compositing().
1500     if (isDirectRendering())
1501         ewk_view_mark_for_sync(m_viewImpl->view());
1502     else
1503 #endif
1504     setViewNeedsDisplay(IntRect(IntPoint(), viewSize()));
1505
1506 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
1507     updateScrollbar();
1508 #endif
1509
1510 #if ENABLE(TIZEN_SCREEN_READER)
1511     m_viewImpl->page()->recalcScreenReaderFocusRect();
1512 #endif
1513 }
1514
1515 void PageClientEvasGL::drawContents()
1516 {
1517     if (!drawingArea() || !(drawingArea()->layerTreeCoordinatorProxy()))
1518         return;
1519
1520     WebLayerTreeRenderer* renderer = drawingArea()->layerTreeCoordinatorProxy()->layerTreeRenderer();
1521     if (!renderer)
1522         return;
1523
1524     if (!makeContextCurrent())
1525         return;
1526
1527     WebCore::TransformationMatrix matrix;
1528     IntRect clipRect;
1529     IntSize ewkViewSize = viewSize();
1530
1531 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1532     if (isDirectRendering()) {
1533         Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewImpl->view()));
1534         m_angle = ecore_evas_rotation_get(ee);
1535         renderer->setAngle(m_angle);
1536         matrix.rotate3d(0.0, 0.0, 1.0, 360 - m_angle);
1537
1538         if (m_angle == 90 || m_angle == 270) {
1539             glViewport(0, 0, ewkViewSize.height(), ewkViewSize.width());
1540             if (m_angle == 90)
1541                 matrix.translate(-ewkViewSize.width(), 0);
1542             else if (m_angle == 270)
1543                 matrix.translate(0, -ewkViewSize.height());
1544             clipRect = IntRect(IntPoint(), ewkViewSize.transposedSize());
1545         } else {
1546             glViewport(0, 0, ewkViewSize.width(), ewkViewSize.height());
1547             if (m_angle == 180)
1548                 matrix.translate(-ewkViewSize.width(), -ewkViewSize.height());
1549             clipRect = IntRect(IntPoint(), ewkViewSize);
1550         }
1551     } else
1552 #endif
1553     {
1554         glViewport(0, 0, ewkViewSize.width(), ewkViewSize.height());
1555         clipRect = IntRect(IntPoint(), ewkViewSize);
1556     }
1557
1558     matrix *= m_viewImpl->transformToView().toTransformationMatrix();
1559
1560 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE_BACKUP_IMAGE)
1561     if (m_shouldMakeBackupTexture) {
1562         glViewport(0, 0, m_initialViewRect.width(), m_initialViewRect.height());
1563         glClearColor(1, 1, 1, 1);
1564         glClear(GL_COLOR_BUFFER_BIT);
1565         renderer->paintToBackupTexture(matrix, 1.0f, m_initialViewRect, m_bgColor);
1566         m_shouldMakeBackupTexture = false;
1567     } else if (m_shouldShowBackupTexture) {
1568         matrix.makeIdentity();
1569         glViewport(0, 0, m_initialViewRect.width(), m_initialViewRect.height());
1570         renderer->showBackupTexture(matrix, 1.0f, m_initialViewRect);
1571     } else
1572 #endif
1573     renderer->paintToCurrentGLContext(matrix, 1.0f, clipRect, m_bgColor);
1574 }
1575
1576 void PageClientEvasGL::didRenderFrame()
1577 {
1578     ewkViewFrameRendered(m_viewImpl->view());
1579     PageClientImpl::didRenderFrame();
1580 }
1581
1582 bool PageClientEvasGL::makeContextCurrent()
1583 {
1584     return evas_gl_make_current(m_evasGL, m_surface, m_context);
1585 }
1586
1587 void PageClientEvasGL::initializeAcceleratedCompositingMode()
1588 {
1589     Evas* evas = evas_object_evas_get(m_viewImpl->view());
1590
1591     m_config = evas_gl_config_new();
1592 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1593     char* directRenderingEnv = getenv("TIZEN_WEBKIT_DIRECT_RENDERING");
1594     if (!directRenderingEnv || atoi(directRenderingEnv)) {
1595         setenv("EVAS_GL_DIRECT_OVERRIDE", "1", 1);
1596         m_config->options_bits = EVAS_GL_OPTIONS_DIRECT;
1597     }
1598 #endif
1599     m_config->color_format = EVAS_GL_RGBA_8888;
1600     m_config->depth_bits = EVAS_GL_DEPTH_BIT_24;
1601     m_config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
1602
1603     m_evasGL = evas_gl_new(evas);
1604     if (!m_evasGL) {
1605         evas_gl_config_free(m_config);
1606         m_config = 0;
1607         TIZEN_LOGE("failed to create evas_gl");
1608         return;
1609     }
1610
1611     Evas_GL_API* evasGlApi = evas_gl_api_get(m_evasGL);
1612     if (!evasGlApi) {
1613         evas_gl_free(m_evasGL);
1614         m_evasGL = 0;
1615         evas_gl_config_free(m_config);
1616         m_config = 0;
1617         TIZEN_LOGE("failed to get evas_gl_api");
1618         return;
1619     }
1620     WebCore::EvasGlApiInterface::shared().initialize(evasGlApi);
1621
1622     m_context = evas_gl_context_create(m_evasGL, 0);
1623     if (!m_context) {
1624         evas_gl_free(m_evasGL);
1625         m_evasGL = 0;
1626         evas_gl_config_free(m_config);
1627         m_config = 0;
1628         TIZEN_LOGE("failed to create evas_gl_context");
1629         return;
1630     }
1631
1632     setTargetSurface();
1633     m_isAcceleratedCompositingModeInitialized =  true;
1634 }
1635
1636 void PageClientEvasGL::finalizeAcceleratedCompositingMode()
1637 {
1638     if (m_evasGL) {
1639         if (m_surface) {
1640             evas_gl_surface_destroy(m_evasGL, m_surface);
1641             m_surface = 0;
1642         }
1643         if (m_context) {
1644             evas_gl_context_destroy(m_evasGL, m_context);
1645             m_context = 0;
1646         }
1647         if (m_config) {
1648             evas_gl_config_free(m_config);
1649             m_config = 0;
1650         }
1651         evas_gl_free(m_evasGL);
1652         m_evasGL = 0;
1653     }
1654
1655 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1656     setenv("EVAS_GL_DIRECT_OVERRIDE", "0", 1);
1657 #endif
1658     m_isAcceleratedCompositingModeInitialized = false;
1659 }
1660
1661 void PageClientEvasGL::enterAcceleratedCompositingMode(const LayerTreeContext&)
1662 {
1663     if (!m_isAcceleratedCompositingModeInitialized)
1664         initializeAcceleratedCompositingMode();
1665 }
1666
1667 void PageClientEvasGL::exitAcceleratedCompositingMode()
1668 {
1669     if (m_isAcceleratedCompositingModeInitialized)
1670         finalizeAcceleratedCompositingMode();
1671 }
1672
1673 void PageClientEvasGL::setTargetSurface()
1674 {
1675     if (!m_evasGL)
1676         return;
1677
1678     int width, height;
1679     evas_object_geometry_get(m_viewImpl->view(), 0, 0, &width, &height);
1680     if (width == 0 || height == 0)
1681         return;
1682
1683     m_surface = evas_gl_surface_create(m_evasGL, m_config, width, height);
1684     if (!m_surface) {
1685         TIZEN_LOGE("failed to create Evas_GL_Surface");
1686         return;
1687     }
1688
1689 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1690     if (isDirectRendering())
1691         makeContextCurrent();
1692     else
1693 #endif
1694     {
1695         if (makeContextCurrent()) {
1696             glViewport(0, 0, width, height);
1697             glClearColor(1.0, 1.0, 1.0, 1.0);
1698             glClear(GL_COLOR_BUFFER_BIT);
1699             glFinish();
1700         }
1701     }
1702
1703     Evas_Native_Surface nativeSurface;
1704     if (evas_gl_native_surface_get(m_evasGL, m_surface, &nativeSurface))
1705         ewk_view_image_native_surface_set(m_viewImpl->view(), &nativeSurface);
1706 }
1707 #endif
1708
1709 } // namespace WebKit