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