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