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