[WK2] Remove input context for fullscreen keypad
[profile/ivi/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 "DrawingAreaMessages.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
37 #if OS(TIZEN)
38 #include "DrawingAreaProxyImpl.h"
39 #include "Editor.h"
40 #include "EflScreenUtilities.h"
41 #include "LayerTreeHostProxy.h"
42 #include "OpenGLShims.h"
43 #include "WebContextMenuProxyEfl.h"
44 #include "WebLayerTreeRenderer.h"
45 #include "WebPageGroup.h"
46 #include "WebPageMessages.h"
47 #include "WebPopupMenuProxyEfl.h"
48 #include "WebPreferences.h"
49 #include "ewk_view_private.h"
50 #include "ewk_view.h"
51 #include <Ecore_Evas.h>
52 #include <Ecore_X.h>
53
54 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
55 #include "MainFrameScrollbarEfl.h"
56 #endif
57
58 #if ENABLE(TIZEN_INPUT_COLOR_PICKER)
59 #include "WebColorChooserProxyEfl.h"
60 #endif // TIZEN_INPUT_COLOR_PICKER
61
62 #endif
63
64 using namespace WebCore;
65
66 namespace WebKit {
67
68 #if ENABLE(TIZEN_ISF_PORT)
69 static void imfPreeditChangedCb(void* client, Ecore_IMF_Context* context, void* eventInfo)
70 {
71     static_cast<PageClientImpl*>(client)->imContextPreeditChanged();
72 }
73
74 static void imfEventCommittedCb(void* client, Ecore_IMF_Context* context, void* eventInfo)
75 {
76     static_cast<PageClientImpl*>(client)->imContextCommitted(static_cast<char*>(eventInfo));
77 }
78
79 static void imfInputPanelStateEventCb(void *client, Ecore_IMF_Context *ctx, int state)
80 {
81     LOG(ISF, "%s\n", __func__);
82
83     PageClientImpl* pageClient = static_cast<PageClientImpl*>(client);
84     if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
85         pageClient->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
86         evas_object_smart_callback_call(pageClient->viewWidget(), "editorclient,ime,closed", 0);
87         LOG(ISF, "[SIGNAL] editorclient,ime,closed\n");
88
89 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
90         pageClient->setIsTextSelectionMode(false);
91 #endif
92     } else if (state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
93         pageClient->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
94         evas_object_smart_callback_call(pageClient->viewWidget(), "editorclient,ime,opened", 0);
95         LOG(ISF, "[SIGNAL] editorclient,ime,opened\n");
96     }
97 }
98
99 static Eina_Bool imfRetrieveSurroundingCb(void* client, Ecore_IMF_Context* context, char** text, int* cursorPos)
100 {
101     LOG(ISF, "%s\n", __func__);
102
103     PageClientImpl* pageClient = static_cast<PageClientImpl*>(client);
104     if (!pageClient)
105         return EINA_FALSE;
106
107     if (!pageClient->page()->focusedFrame())
108         return EINA_FALSE;
109
110     *cursorPos = pageClient->page()->getCursorOffsetPosition();
111     String content = pageClient->page()->getContentOfPosition();
112     *text = content.length() ? strdup(content.utf8().data()) : strdup("");
113
114     LOG(ISF, "Retrieve surrounding text : %s pos : %d\n", *text, *cursorPos);
115     return EINA_TRUE;
116 }
117
118 static void imfContextDeleteSurroundingCb(void* client, Ecore_IMF_Context* context, void* eventInfo)
119 {
120     LOG(ISF, "%s\n", __func__);
121
122     PageClientImpl* pageClient = static_cast<PageClientImpl*>(client);
123     Ecore_IMF_Event_Delete_Surrounding* event = static_cast<Ecore_IMF_Event_Delete_Surrounding*>(eventInfo);
124     if (!pageClient || !event)
125         return;
126
127     if (!pageClient->page()->focusedFrame())
128         return;
129
130     if (pageClient->page()->deleteSurroundingPosition())
131         pageClient->setCursorPosition();
132 }
133 #endif
134
135 PageClientImpl::PageClientImpl(WebContext* context, WebPageGroup* pageGroup, Evas_Object* viewWidget)
136     : m_viewWidget(viewWidget)
137 #if OS(TIZEN)
138     , m_viewportConstraints()
139     , m_viewFocused(false)
140     , m_viewWindowActive(true)
141     , m_preventNextCompositionCommit(false)
142     , m_layoutAndScaleState(BeforeCommitLoad)
143     , m_inputMethod(0)
144     , m_mousePressed(0)
145 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
146     , m_visibleContentRect(IntRect())
147     , m_scaleFactor(1.0f)
148     , m_visibleContentRectForDrawContents(IntRect())
149     , m_scaleFactorForDrawContents(1.0f)
150 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
151     , m_evasGL(0)
152     , m_context(0)
153     , m_surface(0)
154     , m_config(0)
155 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
156     , m_angle(0)
157 #endif
158     , m_isAcceleratedCompositingModeInitialized(false)
159 #endif
160 #endif
161     , m_suspendPainting(false)
162     , m_suspendResource(false)
163     , m_suspendRequested(false)
164     , m_isVisible(true)
165     , m_isScrollableNodeFocused(false)
166 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
167     , m_isContextMenuVisible(false)
168 #endif
169 #endif // #if OS(TIZEN)
170 {
171     m_page = context->createWebPage(this, pageGroup);
172
173 #if OS(TIZEN)
174     m_page->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true);
175     m_page->pageGroup()->preferences()->setForceCompositingMode(true);
176     m_page->pageGroup()->preferences()->setFrameFlatteningEnabled(true);
177     m_page->pageGroup()->preferences()->setAllowUniversalAccessFromFileURLs(true);
178
179     if (m_viewWidget) {
180         int deviceWidth, deviceHeight;
181         ecore_evas_screen_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewWidget)), 0, 0, &deviceWidth, &deviceHeight);
182         m_page->pageGroup()->preferences()->setDeviceWidth(deviceWidth);
183         m_page->pageGroup()->preferences()->setDeviceHeight(deviceHeight);
184     }
185
186 #if ENABLE(TIZEN_VIEWPORT_META_TAG)
187     m_page->pageGroup()->preferences()->setDevicePixelRatio(getMobileDPI());
188 #else
189     m_page->pageGroup()->preferences()->setDevicePixelRatio(getDPI());
190 #endif
191 #endif
192
193     m_page->initializeWebPage();
194
195 #if OS(TIZEN)
196 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
197     m_textSelection = TextSelection::create(viewWidget, m_page.get(), this);
198 #endif
199
200 #if ENABLE(TIZEN_ISF_PORT)
201     initializeInputMethod();
202 #endif
203 #endif
204
205 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE) && !ENABLE(TIZEN_WEBKIT2_EFL_WTR)
206     m_page->setUseFixedLayout(true);
207 #endif
208 #if ENABLE(FULLSCREEN_API)
209     m_page->fullScreenManager()->setWebView(viewWidget);
210 #endif
211
212 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
213     initializeAcceleratedCompositingMode();
214     setBackgroundColor(1, 1, 1, 1);
215 #endif
216 }
217
218 PageClientImpl::~PageClientImpl()
219 {
220 #if ENABLE(TIZEN_ISF_PORT)
221     terminateInputMethod();
222 #endif
223 }
224
225 #if OS(TIZEN)
226 PageClientImpl::ViewportConstraints PageClientImpl::computeViewportConstraints(const WebCore::ViewportAttributes& attributes)
227 {
228     PageClientImpl::ViewportConstraints constraints;
229     constraints.initialScale = attributes.initialScale * attributes.devicePixelRatio;
230     constraints.minimumScale = attributes.minimumScale * attributes.devicePixelRatio;
231     constraints.maximumScale = attributes.maximumScale * attributes.devicePixelRatio;
232     constraints.userScalable = attributes.userScalable && (constraints.minimumScale < constraints.maximumScale);
233     constraints.layoutSize = attributes.layoutSize;
234 #if ENABLE(TIZEN_VIEWPORT_META_TAG)
235     constraints.devicePixelRatio = attributes.devicePixelRatio;
236 #endif
237
238     return constraints;
239 }
240
241 double PageClientImpl::adjustScaleWithViewport(double scale)
242 {
243     if (scale < m_viewportConstraints.minimumScale)
244         scale = m_viewportConstraints.minimumScale;
245     if (scale > m_viewportConstraints.maximumScale)
246         scale = m_viewportConstraints.maximumScale;
247     return scale;
248 }
249
250 #if USE(TILED_BACKING_STORE) && ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
251 void PageClientImpl::updateViewportSize(const IntSize& viewportSize)
252 {
253     // update device width & height
254     int deviceWidth = WebCore::getDefaultScreenResolution().width();
255     int deviceHeight = WebCore::getDefaultScreenResolution().height();
256     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewWidget));
257     int angle = ecore_evas_rotation_get(ee);
258     if (angle == 90 || angle == 270) {
259         int tempWidth = deviceWidth;
260         deviceWidth = deviceHeight;
261         deviceHeight = tempWidth;
262     }
263     m_page->pageGroup()->preferences()->setDeviceWidth(deviceWidth);
264     m_page->pageGroup()->preferences()->setDeviceHeight(deviceHeight);
265
266     m_visibleContentRect.setSize(viewportSize);
267     m_page->setViewportSize(viewportSize);
268     if (m_surface) {
269         evas_gl_surface_destroy(m_evasGL, m_surface);
270         m_surface = 0;
271     }
272     setTargetSurface();
273 }
274 #endif
275
276 void PageClientImpl::initializeScale()
277 {
278     m_layoutAndScaleState = DidFirstVisuallyNonEmptyLayout;
279     resumePainting();
280
281     // Set initial scale factor.
282     float initialScaleFactor = m_viewportConstraints.initialScale;
283     double defaultViewLevel = m_page->pageGroup()->preferences()->defaultViewLevel();
284 #if ENABLE(TIZEN_VIEWPORT_META_TAG)
285     // ViewportConstraints::devicePixelRatio has dependency on TIZEN_VIEWPORT_META_TAG
286     defaultViewLevel *= m_viewportConstraints.devicePixelRatio;
287 #endif
288     if (defaultViewLevel)
289         initialScaleFactor = defaultViewLevel;
290     else
291         initialScaleFactor = m_viewportConstraints.minimumScale;
292
293
294     initialScaleFactor = adjustScaleWithViewport(initialScaleFactor);
295 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
296     // Call setVisibleContentRect() with current scroll position.
297     // Because scroll position can be changed by HistoryController when we go back and foward
298     setVisibleContentRect(scrollPosition(), initialScaleFactor, FloatPoint());
299 #else
300     // Set initial scale.
301     m_page->scalePage(initialScaleFactor, IntPoint(0, 0));
302 #endif
303 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC)
304     m_layoutAndScaleState = DidFirstFrameRendered;
305 #endif
306 }
307
308 void PageClientImpl::updateScale()
309 {
310     if (m_layoutAndScaleState == BeforeCommitLoad) {
311         // Before commit load, we don't need to update visible content rect.
312         // ex) While we navigate from m.mt.co.kr to www.mt.co.kr(desktop),
313         // contents size is changed and updateLayoutAndScale() is called even next page is not committed yet.
314         return;
315     } else if (m_layoutAndScaleState == DidCommitLoaded) {
316         // m_visibleContentRect.location should be set to (0, 0).
317         // If location is not (0, 0), user scrolled flag is set to TRUE by calling setVisibleContentRect().
318         m_visibleContentRect.setLocation(IntPoint(0, 0));
319     }
320
321     // We should update scale factor and scroll position even they are not changed.
322     // Because, contents size can be changed smaller by IME and visible content rect can be outside of contents boundary.
323 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
324     setVisibleContentRect(scrollPosition(), m_viewportConstraints.initialScale, FloatPoint());
325 #else
326     m_page->scalePage(m_viewportConstraints.initialScale, m_page->scrollPosition());
327 #endif
328 }
329
330 void PageClientImpl::setFocusedNodeRect(const IntRect& focusedNodeRect)
331 {
332     if (!focusedNodeRect.isEmpty()) {
333         m_focusedNodeRect = focusedNodeRect;
334     }
335 }
336
337 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
338 bool PageClientImpl::scrollBy(IntSize scrollOffset)
339 {
340 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
341     if (m_isScrollableNodeFocused && page()->scrollOverflow(FloatPoint(scrollOffset.width(), scrollOffset.height()))) {
342         displayViewport();
343         return false;
344     }
345 #endif
346
347     IntPoint newScrollPosition = scrollPosition();
348     newScrollPosition.move(scrollOffset);
349     setVisibleContentRect(newScrollPosition, scaleFactor(), FloatPoint(scrollOffset.width(), scrollOffset.height()));
350     displayViewport();
351     return true;
352 }
353
354 void PageClientImpl::scrollTo(IntPoint scrollPosition)
355 {
356     setVisibleContentRect(scrollPosition, scaleFactor(), FloatPoint());
357     displayViewport();
358 }
359 #endif // #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
360
361 #endif // #if OS(TIZEN)
362
363 // PageClient
364 PassOwnPtr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy()
365 {
366     return DrawingAreaProxyImpl::create(m_page.get());
367 }
368
369 void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect)
370 {
371 #if !ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
372     drawContents();
373 #endif
374     ewk_view_display(m_viewWidget, rect);
375 }
376
377 void PageClientImpl::displayView()
378 {
379     notImplemented();
380 }
381
382 void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize&)
383 {
384     setViewNeedsDisplay(scrollRect);
385 }
386
387 WebCore::IntSize PageClientImpl::viewSize()
388 {
389     int width, height;
390     evas_object_geometry_get(m_viewWidget, 0, 0, &width, &height);
391     return IntSize(width, height);
392 }
393
394 bool PageClientImpl::isViewVisible()
395 {
396     return m_isVisible;
397 }
398
399 bool PageClientImpl::isViewInWindow()
400 {
401     notImplemented();
402     return true;
403 }
404
405 void PageClientImpl::processDidCrash()
406 {
407     notImplemented();
408 }
409
410 void PageClientImpl::didRelaunchProcess()
411 {
412     notImplemented();
413 }
414
415 void PageClientImpl::pageClosed()
416 {
417     notImplemented();
418 }
419
420 void PageClientImpl::toolTipChanged(const String&, const String&)
421 {
422     notImplemented();
423 }
424
425 void PageClientImpl::setCursor(const Cursor& cursor)
426 {
427 #if ENABLE(TIZEN_WEBKIT2_CURSOR_PARTIAL_EARLY_MERGE)
428     ewk_view_cursor_set(m_viewWidget, cursor);
429 #endif
430 }
431
432 void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
433 {
434     notImplemented();
435 }
436
437 void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes& attributes)
438 {
439     m_viewportConstraints = computeViewportConstraints(attributes);
440     updateScale();
441
442 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
443     updateTextSelectionHandlesAndContextMenu(true);
444 #endif
445 }
446
447 #if OS(TIZEN)
448 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> command, WebPageProxy::UndoOrRedo undoOrRedo)
449 {
450     if (undoOrRedo == WebPageProxy::Undo)
451         m_undoCommands.append(command);
452     else
453         m_redoCommands.append(command);
454 }
455
456 void PageClientImpl::clearAllEditCommands()
457 {
458     m_undoCommands.clear();
459     m_redoCommands.clear();
460 }
461
462 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
463 {
464     if (undoOrRedo == WebPageProxy::Undo)
465         return !m_undoCommands.isEmpty();
466     else
467         return !m_redoCommands.isEmpty();
468 }
469
470 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
471 {
472     if (undoOrRedo == WebPageProxy::Undo) {
473         m_undoCommands.last()->unapply();
474         m_undoCommands.removeLast();
475     } else {
476         m_redoCommands.last()->reapply();
477         m_redoCommands.removeLast();
478     }
479 }
480 #else
481 void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo)
482 {
483     notImplemented();
484 }
485
486 void PageClientImpl::clearAllEditCommands()
487 {
488     notImplemented();
489 }
490
491 bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo)
492 {
493     notImplemented();
494     return false;
495 }
496
497 void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo)
498 {
499     notImplemented();
500 }
501 #endif
502
503 FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& viewRect)
504 {
505     notImplemented();
506     return viewRect;
507 }
508
509 FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect)
510 {
511     notImplemented();
512     return viewRect;
513 }
514
515 IntPoint PageClientImpl::screenToWindow(const IntPoint& point)
516 {
517     notImplemented();
518     return point;
519 }
520
521 IntRect PageClientImpl::windowToScreen(const IntRect&)
522 {
523     notImplemented();
524     return IntRect();
525 }
526
527 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
528 {
529     notImplemented();
530 }
531
532 #if ENABLE(TOUCH_EVENTS)
533 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
534 {
535 #if OS(TIZEN)
536     ewk_view_touch_event_handler_result_set(m_viewWidget, event.type(), wasEventHandled);
537 #else
538     notImplemented();
539 #endif // #if OS(TIZEN)
540 }
541 #endif
542
543 PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page)
544 {
545 #if ENABLE(TIZEN_WEBKIT2_POPUP)
546     return WebPopupMenuProxyEfl::create(m_viewWidget, page);
547 #endif
548 }
549
550 PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page)
551 {
552 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
553     return WebContextMenuProxyEfl::create(m_viewWidget, page, this);
554 #else
555     notImplemented();
556     return 0;
557 #endif
558 }
559
560 #if ENABLE(INPUT_TYPE_COLOR)
561 #if ENABLE(TIZEN_INPUT_COLOR_PICKER)
562 PassRefPtr<WebColorChooserProxy> PageClientImpl::createColorChooserProxy(WebPageProxy* page, const WebCore::Color& initialColor)
563 #else
564 PassRefPtr<WebColorChooserProxy> PageClientImpl::createColorChooserProxy(WebPageProxy*, const WebCore::Color&)
565 #endif // ENABLE(TIZEN_INPUT_COLOR_PICKER)
566 {
567 #if ENABLE(TIZEN_INPUT_COLOR_PICKER)
568     return WebColorChooserProxyEfl::create(m_viewWidget, page, initialColor);
569 #endif // ENABLE(TIZEN_INPUT_COLOR_PICKER)
570     notImplemented();
571     return 0;
572 }
573 #endif
574
575 void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool, bool)
576 {
577     notImplemented();
578 }
579
580 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
581 void PageClientImpl::initializeAcceleratedCompositingMode()
582 {
583     Evas_Object* view = page()->viewWidget();
584     Evas* evas = evas_object_evas_get(view);
585
586     m_config = evas_gl_config_new();
587 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
588     setenv("EVAS_GL_DIRECT_OVERRIDE", "1", 1);
589     m_config->options_bits = EVAS_GL_OPTIONS_DIRECT;
590 #endif
591     m_config->color_format = EVAS_GL_RGBA_8888;
592     m_config->depth_bits = EVAS_GL_DEPTH_BIT_24;
593     m_config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
594
595     m_evasGL = evas_gl_new(evas);
596     if (!m_evasGL) {
597         evas_gl_config_free(m_config);
598         m_config = 0;
599         return;
600     }
601
602     Evas_GL_API* evasGlApi = evas_gl_api_get(m_evasGL);
603     if (!evasGlApi) {
604         evas_gl_free(m_evasGL);
605         m_evasGL = 0;
606         evas_gl_config_free(m_config);
607         m_config = 0;
608         return;
609     }
610     WebCore::EvasGlApiInterface::shared().initialize(evasGlApi);
611
612     m_context = evas_gl_context_create(m_evasGL, 0);
613     if (!m_context) {
614         evas_gl_free(m_evasGL);
615         m_evasGL = 0;
616         evas_gl_config_free(m_config);
617         m_config = 0;
618         return;
619     }
620
621     setTargetSurface();
622
623     m_isAcceleratedCompositingModeInitialized =  true;
624 }
625
626 void PageClientImpl::finalizeAcceleratedCompositingMode()
627 {
628     if (m_evasGL) {
629         if (m_surface) {
630             evas_gl_surface_destroy(m_evasGL, m_surface);
631             m_surface = 0;
632         }
633         if (m_context) {
634             evas_gl_context_destroy(m_evasGL, m_context);
635             m_context = 0;
636         }
637         if (m_config) {
638             evas_gl_config_free(m_config);
639             m_config = 0;
640         }
641         evas_gl_free(m_evasGL);
642         m_evasGL = 0;
643     }
644
645 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
646     setenv("EVAS_GL_DIRECT_OVERRIDE", "0", 1);
647 #endif
648
649     m_isAcceleratedCompositingModeInitialized = false;
650 }
651
652 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&)
653 {
654     if (!m_isAcceleratedCompositingModeInitialized)
655         initializeAcceleratedCompositingMode();
656 }
657
658 void PageClientImpl::exitAcceleratedCompositingMode()
659 {
660     if (m_isAcceleratedCompositingModeInitialized)
661         finalizeAcceleratedCompositingMode();
662 }
663
664 void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&)
665 {
666     notImplemented();
667 }
668
669 void PageClientImpl::updateLayoutAndScaleIfNeeded()
670 {
671     if (m_layoutAndScaleState == DidFirstVisuallyNonEmptyLayout) {
672         // Consider first frame rendered time after first visually nonempty layout finished,
673         // as a right time to update scale factor and scroll position.
674         m_layoutAndScaleState = DidFirstFrameRendered;
675     }
676 }
677
678 void PageClientImpl::setBackgroundColor(double red, double green, double blue, double alpha)
679 {
680     WebCore::RGBA32 rgba= WebCore::makeRGBA32FromFloats((float)red, (float)green, (float)blue, (float)alpha);
681     m_bgColor.setRGB(rgba);
682 }
683 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC)
684
685 void PageClientImpl::didChangeScrollbarsForMainFrame() const
686 {
687     notImplemented();
688 }
689
690 #if OS(TIZEN)
691 void PageClientImpl::didStartProgress()
692 {
693     m_layoutAndScaleState = BeforeCommitLoad;
694 #if ENABLE(TIZEN_ISF_PORT)
695     if (getInputMethodState()) {
696         LOG(ISF, "%s\n", __func__);
697         setInputMethodState(false, String(), String());
698     }
699 #endif
700 }
701
702 void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame()
703 {
704     if (m_layoutAndScaleState < DidFirstVisuallyNonEmptyLayout) {
705         // Sometimes, didFirstVisuallyNonEmptyLayoutForMainFrame() is called after didFinishLoadForMainFrame()
706         // ex) cached page, local contents, load image resources directly.
707         initializeScale();
708     }
709 }
710
711 void PageClientImpl::didFinishLoadForMainFrame()
712 {
713     if (m_layoutAndScaleState < DidFirstVisuallyNonEmptyLayout) {
714         // We have to initialize layout and scale here if it is not done
715         // Sometimes, didFirstVisuallyNonEmptyLayoutForMainFrame() is called after didFinishLoadForMainFrame()
716         // ex) cached page, local contents, load image resources directly.
717         initializeScale();
718     }
719 }
720
721 void PageClientImpl::didFinishProgress()
722 {
723     if (m_layoutAndScaleState == BeforeCommitLoad) {
724         // If there was nothing to load committed, reset state.
725         // ex) When we open download popup, then didFinishProgress() is called right after didtartProgress().
726         m_layoutAndScaleState = DidFirstFrameRendered;
727     }
728
729     if (!m_suspendRequested)
730         return;
731
732     m_suspendRequested = false;
733     suspendPainting();
734     suspendJavaScriptAndResource();
735 }
736
737 void PageClientImpl::didChangeContentsSize(const WebCore::IntSize size)
738 {
739 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
740     IntSize scaledSize = size;
741     scaledSize.scale(scaleFactor());
742
743     if (m_horizontalScrollbar)
744         m_horizontalScrollbar->setProportion(viewSize().width(), scaledSize.width());
745     if (m_verticalScrollbar)
746         m_verticalScrollbar->setProportion(viewSize().height(), scaledSize.height());
747 #endif
748
749 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
750     if (drawingArea()->layerTreeHostProxy())
751         drawingArea()->layerTreeHostProxy()->setContentsSize(WebCore::FloatSize(size.width(), size.height()));
752 #endif
753
754     // FIXME: Currently minimum scale is recalculated by contents' width
755     // if contents' width exceeds viewport layout width and userScalable is true.
756     // But we should recalculate this when viewport argument's minimum scale is not fixed.
757     double previousMinimumScale = m_viewportConstraints.minimumScale;
758     double minimumScaleByContentWidth = (double)viewSize().width() / size.width();
759     double defaultViewLevel = m_page->pageGroup()->preferences()->defaultViewLevel();
760
761     // If contents width exceeds viewport layout width and content is userScalable,
762     // update minimumScale.
763     if (m_viewportConstraints.userScalable && previousMinimumScale > minimumScaleByContentWidth)
764         m_viewportConstraints.minimumScale = minimumScaleByContentWidth;
765
766     // If scale factor was minimized, then minimize new scale factor too.
767     double newScaleFactor = scaleFactor();
768     if (scaleFactor() == previousMinimumScale && m_viewportConstraints.userScalable && !defaultViewLevel)
769         newScaleFactor = m_viewportConstraints.minimumScale;
770 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
771     setVisibleContentRect(m_page->scrollPosition(), newScaleFactor, FloatPoint());
772 #else
773     m_page->scalePage(newScaleFactor, scrollPosition());
774 #endif
775     // After contents size is changed, update scroll bar.
776     displayViewport();
777 }
778
779 void PageClientImpl::setRequestedScaleFactor(double scale)
780 {
781     m_requestedScaleFactor = scale;
782 }
783
784 void PageClientImpl::pageScaleFactorDidChange()
785 {
786     ewk_view_focused_node_adjust(m_viewWidget);
787 }
788
789 #if ENABLE(TOUCH_EVENTS) && ENABLE(TIZEN_GESTURE)
790 void PageClientImpl::cancelTouchEvent()
791 {
792     ewkViewHandleTouchEvent(m_viewWidget, EWK_TOUCH_CANCEL);
793 }
794 #endif
795 #endif // #if OS(TIZEN)
796
797 void PageClientImpl::didCommitLoadForMainFrame(bool)
798 {
799 #if OS(TIZEN)
800     if (m_layoutAndScaleState == BeforeCommitLoad) {
801         // If didCommitLoadForMainFrame() is called after didFirstVisuallyNonEmptyLayoutForMainFrame
802         // Suspend painting until first layout and scale is done.
803         // ex) During the navigation from http://m.mt.co.kr/new/ to http://www.mt.co.kr(desktop)
804         suspendPainting();
805         m_layoutAndScaleState = DidCommitLoaded;
806     }
807     return;
808 #endif
809     notImplemented();
810 }
811
812 void PageClientImpl::didFinishLoadingDataForCustomRepresentation(const String&, const CoreIPC::DataReference&)
813 {
814     notImplemented();
815 }
816
817 double PageClientImpl::customRepresentationZoomFactor()
818 {
819     notImplemented();
820     return 0;
821 }
822
823 void PageClientImpl::setCustomRepresentationZoomFactor(double)
824 {
825     notImplemented();
826 }
827
828 void PageClientImpl::flashBackingStoreUpdates(const Vector<IntRect>&)
829 {
830     notImplemented();
831 }
832
833 void PageClientImpl::findStringInCustomRepresentation(const String&, FindOptions, unsigned)
834 {
835     notImplemented();
836 }
837
838 void PageClientImpl::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned)
839 {
840     notImplemented();
841 }
842
843 #if OS(TIZEN)
844 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
845 void PageClientImpl::setInputMethodState(bool active, const AtomicString& inputType, const String& inputValue)
846 #else
847 void PageClientImpl::setInputMethodState(bool active)
848 #endif
849 {
850 #if ENABLE(TIZEN_ISF_PORT)
851     LOG(ISF, "%s\n", __func__);
852
853     if (!initializeInputMethod())
854         return;
855
856     Ewk_Setting* ewkSetting = ewk_view_setting_get(m_viewWidget);
857     bool autofocused = ewk_setting_show_ime_on_autofocus_get(ewkSetting);
858     bool defaultKeypadEnabled = ewk_setting_enable_default_keypad_get(ewkSetting);
859
860     LOG(ISF, "- active(%d), m_mousePressed(%d), autofocused(%d), defaultKeypadEnabled(%d)\n", active, m_mousePressed, autofocused, defaultKeypadEnabled);
861
862     if (!autofocused && active && !m_mousePressed) {
863         LOG(ISF, "[FAIL] Autofocus is disabled\n");
864         return;
865     }
866
867     Ecore_IMF_Input_Panel_State state = ecore_imf_context_input_panel_state_get(m_inputMethod);
868     if (active) {
869
870         if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
871             Eina_Rectangle rect;
872             ecore_imf_context_input_panel_geometry_get(m_inputMethod, &rect.x, &rect.y, &rect.w, &rect.h);
873             evas_object_smart_callback_call(m_viewWidget, "inputmethod,changed", &rect);
874             LOG(ISF, "[SIGNAL] inputmethod,changed (%d,%d,%d,%d)\n", rect.x, rect.y, rect.w, rect.h);
875         }
876
877         if (!defaultKeypadEnabled) {
878             terminateInputMethod();
879             LOG(ISF, "[FAIL] %s : Default keypad disabled\n", __func__);
880             return;
881         }
882
883 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
884         String type = inputType.string();
885         LOG(ISF, "- Input type (%s)\n", type.utf8().data());
886
887         // Input picker
888         if (type == "date") {
889             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_DATE, inputValue);
890             return;
891         } else if (type == "datetime") {
892             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_DATETIME, inputValue);
893             return;
894         } else if (type == "datetime-local") {
895             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_DATETIMELOCAL, inputValue);
896             return;
897         } else if (type == "month") {
898             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_MONTH, inputValue);
899             return;
900         } else if (type == "time") {
901             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_TIME, inputValue);
902             return;
903         } else if (type == "week") {
904             ewkViewInputPickerRequest(m_viewWidget, EWK_INPUT_TYPE_WEEK, inputValue);
905             return;
906         }
907
908 #if ENABLE(TIZEN_DATALIST_ELEMENT)
909         Vector<String> optionList = page()->getFocusedInputElementDataList();
910         if (optionList.size() > 0) {
911             if (type == "tel")
912                 ewkViewDataListShowRequest(m_viewWidget, EWK_INPUT_TYPE_TELEPHONE, optionList);
913             else if (type == "number")
914                 ewkViewDataListShowRequest(m_viewWidget, EWK_INPUT_TYPE_NUMBER, optionList);
915             else if (type == "email")
916                 ewkViewDataListShowRequest(m_viewWidget, EWK_INPUT_TYPE_EMAIL, optionList);
917             else if (type == "url")
918                 ewkViewDataListShowRequest(m_viewWidget, EWK_INPUT_TYPE_URL, optionList);
919             else
920                 ewkViewDataListShowRequest(m_viewWidget, EWK_INPUT_TYPE_TEXT, optionList);
921
922             return;
923         }
924 #endif
925
926         // Allow Prediction text
927         if (type == "password")
928             ecore_imf_context_prediction_allow_set(m_inputMethod, false);
929         else
930             ecore_imf_context_prediction_allow_set(m_inputMethod, true);
931
932         // Set Input Method's Layout
933         if (type == "tel")
934             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER);
935         else if (type == "number")
936             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER);
937         else if (type == "email")
938             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL);
939         else if (type == "url")
940             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_URL);
941         else if (type == "password")
942             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD);
943         else
944             ecore_imf_context_input_panel_layout_set(m_inputMethod, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
945 #endif // ENABLE(TIZEN_INPUT_TAG_EXTENSION)
946
947         Evas* evas = evas_object_evas_get(m_viewWidget);
948         ecore_imf_context_client_window_set(m_inputMethod, (void*)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
949         ecore_imf_context_client_canvas_set(m_inputMethod, evas);
950
951         ecore_imf_context_focus_in(m_inputMethod);
952         ecore_imf_context_input_panel_show(m_inputMethod);
953
954         setViewFocused(true);
955         evas_object_focus_set(m_viewWidget, true);
956         LOG(ISF, "- Keypad status : show\n");
957
958         setCursorPosition();
959     } else if (!active && state != ECORE_IMF_INPUT_PANEL_STATE_HIDE && evas_object_focus_get(m_viewWidget)) {
960         if (!defaultKeypadEnabled) {
961             LOG(ISF, "[FAIL] %s Default keypad disabled\n", __func__);
962             return;
963         }
964
965         ecore_imf_context_reset(m_inputMethod);
966         ecore_imf_context_input_panel_hide(m_inputMethod);
967         ecore_imf_context_focus_out(m_inputMethod);
968
969         setViewFocused(false);
970         LOG(ISF, "- Keypad status : hide\n");
971     }
972 #endif // #if ENABLE(TIZEN_ISF_PORT)
973 }
974
975 #if ENABLE(TIZEN_ISF_PORT)
976 void PageClientImpl::setCursorPosition(int preeditPosition)
977 {
978     LOG(ISF, "%s\n", __func__);
979
980     if (!m_inputMethod && !initializeInputMethod())
981         return;
982
983     int offset = 0;
984     offset = page()->getCursorOffsetPosition();
985
986     ecore_imf_context_cursor_position_set(m_inputMethod, offset + preeditPosition);
987     LOG(ISF, "Cursor position : offset %d + preeditPosition %d\n", offset, preeditPosition);
988 }
989
990 bool PageClientImpl::initializeInputMethod()
991 {
992     if (!m_inputMethod) {
993         const char* defaultContextID = ecore_imf_context_default_id_get();
994         if (!defaultContextID)
995             return false;
996
997         m_inputMethod = ecore_imf_context_add(defaultContextID);
998         if (!m_inputMethod)
999             return false;
1000
1001         ecore_imf_context_input_panel_enabled_set(m_inputMethod, false);
1002         ecore_imf_context_input_panel_event_callback_add(m_inputMethod, ECORE_IMF_INPUT_PANEL_STATE_EVENT, imfInputPanelStateEventCb, this);
1003         ecore_imf_context_retrieve_surrounding_callback_set(m_inputMethod, imfRetrieveSurroundingCb, this); // Support for Auto Capitalization
1004         ecore_imf_context_event_callback_add(m_inputMethod, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, imfContextDeleteSurroundingCb, this); //Support for Automatic Full Stop
1005         ecore_imf_context_event_callback_add(m_inputMethod, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, imfPreeditChangedCb, this);
1006         ecore_imf_context_event_callback_add(m_inputMethod, ECORE_IMF_CALLBACK_COMMIT, imfEventCommittedCb, this);
1007     }
1008     return true;
1009 }
1010
1011 void PageClientImpl::terminateInputMethod()
1012 {
1013     if (m_inputMethod) {
1014         ecore_imf_context_input_panel_event_callback_del(m_inputMethod, ECORE_IMF_INPUT_PANEL_STATE_EVENT, imfInputPanelStateEventCb);
1015         ecore_imf_context_event_callback_del(m_inputMethod, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, imfContextDeleteSurroundingCb);
1016         ecore_imf_context_event_callback_del(m_inputMethod, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, imfPreeditChangedCb);
1017         ecore_imf_context_event_callback_del(m_inputMethod, ECORE_IMF_CALLBACK_COMMIT, imfEventCommittedCb);
1018         ecore_imf_context_del(m_inputMethod);
1019         m_inputMethod = 0;
1020     }
1021 }
1022
1023
1024 bool PageClientImpl::getInputMethodState()
1025 {
1026     if (!m_inputMethod && !initializeInputMethod())
1027         return false;
1028
1029     Ecore_IMF_Input_Panel_State state;
1030     state = ecore_imf_context_input_panel_state_get(m_inputMethod);
1031     if (state != ECORE_IMF_INPUT_PANEL_STATE_HIDE)
1032         return true;
1033     return false;
1034 }
1035
1036 void PageClientImpl::handleInputMethodMouseRelease()
1037 {
1038     LOG(ISF, "%s\n", __func__);
1039
1040     m_mousePressed = false;
1041 }
1042
1043 void PageClientImpl::imContextCommitted(char* event)
1044 {
1045     LOG(ISF, "%s\n", __func__);
1046
1047     if (!page()->focusedFrame() || !event)
1048         return;
1049
1050     if (m_preventNextCompositionCommit) {
1051         m_preventNextCompositionCommit = false;
1052         ecore_imf_context_focus_in(m_inputMethod);
1053     }
1054
1055     page()->confirmComposition(String::fromUTF8(event));
1056     LOG(ISF, "confirmComposition : (%s)\n", event);
1057
1058     setCursorPosition();
1059 }
1060
1061 void PageClientImpl::imContextPreeditChanged()
1062 {
1063     LOG(ISF, "%s\n", __func__);
1064
1065     if (!page()->focusedFrame())
1066         return;
1067
1068     char* preeditStr = NULL;
1069     int cursorPosition = 0;
1070
1071     ecore_imf_context_preedit_string_get(m_inputMethod, &preeditStr, &cursorPosition);
1072     if (!preeditStr)
1073         return;
1074
1075     if (cursorPosition) {
1076         int x, y, w, h, scrollX, scrollY, viewX, viewY;
1077         IntRect caretRect(0, 0, 0, 0);
1078
1079         page()->getCaretPosition(caretRect);
1080         caretRect.scale(scaleFactor());
1081
1082         evas_object_geometry_get(m_viewWidget, &viewX, &viewY, NULL, NULL);
1083         ewk_view_scroll_pos_get(m_viewWidget, &scrollX, &scrollY);
1084
1085         x = caretRect.x() - scrollX + viewX;
1086         y = caretRect.y() - scrollY + viewY;
1087         w = caretRect.width();
1088         h = caretRect.height();
1089         ecore_imf_context_cursor_location_set(m_inputMethod, x, y, w, h);
1090
1091         int offset = 0;
1092         offset = page()->getCursorOffsetPosition();
1093
1094         String preeditString = String::fromUTF8(preeditStr);
1095         Vector<CompositionUnderline> underlines;
1096         underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false));
1097         page()->setComposition(preeditString, underlines, offset + cursorPosition);
1098         LOG(ISF, "setComposition : %s\n", preeditStr);
1099
1100         setCursorPosition(cursorPosition);
1101         free(preeditStr);
1102     }
1103
1104 }
1105
1106 void PageClientImpl::handleInputMethodKeydown()
1107 {
1108     LOG(ISF, "%s\n", __func__);
1109
1110     bool defaultKeypadEnabled = ewk_setting_enable_default_keypad_get(ewk_view_setting_get(m_viewWidget));
1111     if (!defaultKeypadEnabled) {
1112         LOG(ISF, "[FAIL] %s Default keypad disabled\n", __func__);
1113         return;
1114     }
1115
1116     m_preventNextCompositionCommit = false;
1117
1118     if (m_inputMethod)
1119         ecore_imf_context_focus_in(m_inputMethod);
1120 }
1121
1122 void PageClientImpl::handleInputMethodMousePress()
1123 {
1124     LOG(ISF, "%s\n", __func__);
1125
1126     m_mousePressed = true;
1127
1128     bool defaultKeypadEnabled = ewk_setting_enable_default_keypad_get(ewk_view_setting_get(m_viewWidget));
1129     if (!defaultKeypadEnabled) {
1130         LOG(ISF, "[FAIL] %s Default keypad disabled\n", __func__);
1131         return;
1132     }
1133
1134     if (!initializeInputMethod())
1135         return;
1136
1137     m_preventNextCompositionCommit = true;
1138     ecore_imf_context_reset(m_inputMethod);
1139 }
1140 #endif // #if ENABLE(TIZEN_ISF_PORT)
1141
1142 void PageClientImpl::updateFormNavigation(int length, int offset)
1143 {
1144     notImplemented();
1145 }
1146
1147 #if USE(TILED_BACKING_STORE)
1148 void PageClientImpl::pageDidRequestScroll(const IntPoint& point)
1149 {
1150 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1151     IntPoint newPoint = point;
1152     newPoint.scale(scaleFactor(), scaleFactor());
1153     setVisibleContentRect(newPoint, scaleFactor(), FloatPoint());
1154     displayViewport();
1155 #endif
1156 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
1157     updateScrollbar(point);
1158 #endif
1159 }
1160 #endif
1161
1162 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1163 void PageClientImpl::adjustVisibleContentRect(IntRect& visibleContentRect, float targetScale)
1164 {
1165     IntSize contentsSize = page()->contentsSize();
1166     contentsSize.scale(targetScale);
1167     if (visibleContentRect.x() > contentsSize.width() - visibleContentRect.width())
1168         visibleContentRect.setX(contentsSize.width() - visibleContentRect.width());
1169     if (visibleContentRect.x() < 0)
1170         visibleContentRect.setX(0);
1171     if (visibleContentRect.y() > contentsSize.height() - visibleContentRect.height())
1172         visibleContentRect.setY(contentsSize.height() - visibleContentRect.height());
1173     if (visibleContentRect.y() < 0)
1174         visibleContentRect.setY(0);
1175 }
1176
1177 void PageClientImpl::setVisibleContentRect(const IntPoint& newScrollPosition, float newScale, const FloatPoint& trajectory)
1178 {
1179     IntRect visibleContentRect = IntRect(newScrollPosition, viewSize());
1180     adjustVisibleContentRect(visibleContentRect, newScale);
1181
1182     m_scaleFactor = newScale;
1183     m_visibleContentRect = visibleContentRect;
1184
1185     // enclosingIntRect produces inconsistent width and height when scale factor is not 1.
1186     // So we removed enclosingIntRect and replaced with floorf and ceilf.
1187     IntRect mapToContentsVisibleContentRect = IntRect(floorf(m_visibleContentRect.x() / newScale),
1188                                                       floorf(m_visibleContentRect.y() / newScale),
1189                                                       ceilf(m_visibleContentRect.width() / newScale),
1190                                                       ceilf(m_visibleContentRect.height() / newScale));
1191
1192     if (drawingArea()) {
1193         drawingArea()->setVisibleContentsRect(mapToContentsVisibleContentRect, newScale, trajectory, FloatPoint(m_visibleContentRect.location()));
1194 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1195         // FIXME: We need to calculate exact visibleRect size here instead of mapToContentsVisibleContentRect.
1196         drawingArea()->setVisibleContentsRectForScrollingContentsLayers(mapToContentsVisibleContentRect);
1197 #endif
1198     }
1199 }
1200
1201 void PageClientImpl::displayViewport()
1202 {
1203 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1204 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1205     // We should not draw here when Direct Rendering is enabled.
1206     // Because we will draw directly when evas is updated - on_pixels_for_accelerated_compositing().
1207     ewk_view_mark_for_sync(m_viewWidget);
1208 #else
1209     setViewNeedsDisplay(IntRect(IntPoint(), viewSize()));
1210 #endif
1211 #endif // #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1212
1213 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
1214     page()->updateScrollbar(m_visibleContentRect.location());
1215 #endif
1216 }
1217
1218 void PageClientImpl::drawContents()
1219 {
1220 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1221     if (!ewk_view_image_get(m_viewWidget))
1222         return;
1223
1224     if (evas_gl_make_current(m_evasGL, m_surface, m_context) != EINA_TRUE)
1225         return;
1226
1227     WebCore::TransformationMatrix matrix;
1228     IntRect clipRect;
1229
1230     if (m_layoutAndScaleState == DidFirstFrameRendered) {
1231         // After first frame is rendered after first nonempty layout finished,
1232         // update scale factor and scroll position.
1233         m_scaleFactorForDrawContents = scaleFactor();
1234         m_visibleContentRectForDrawContents = m_visibleContentRect;
1235     } else {
1236         // Even first frame is not rendered yet, visible content rect size can be changed.
1237         // ex) Navigate user typed URL, then IME is hidden and visible content rect's size can be changed.
1238         m_visibleContentRectForDrawContents.setSize(m_visibleContentRect.size());
1239     }
1240 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1241     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewWidget));
1242     int angle = ecore_evas_rotation_get(ee);
1243     m_angle = angle;
1244     if (drawingArea())
1245         drawingArea()->setAngle(m_angle);
1246     matrix.makeIdentity();
1247     matrix.rotate3d(0.0, 0.0, 1.0, 360 - m_angle);
1248     if (m_angle == 90 || m_angle == 270) {
1249         glViewport(0, 0, m_visibleContentRectForDrawContents.height(), m_visibleContentRectForDrawContents.width());
1250         if (m_angle == 90)
1251             matrix.translate(-m_visibleContentRectForDrawContents.x() -m_visibleContentRectForDrawContents.width(), -m_visibleContentRectForDrawContents.y());
1252         else if (m_angle == 270)
1253             matrix.translate(-m_visibleContentRectForDrawContents.x(), -m_visibleContentRectForDrawContents.y() - m_visibleContentRectForDrawContents.height());
1254         matrix.scale(m_scaleFactor);
1255         clipRect = IntRect(0, 0, m_visibleContentRectForDrawContents.height(), m_visibleContentRectForDrawContents.width());
1256     } else {
1257         glViewport(0, 0, m_visibleContentRectForDrawContents.width(), m_visibleContentRectForDrawContents.height());
1258         if (m_angle == 180) {
1259             matrix.translate(-m_visibleContentRectForDrawContents.x() - m_visibleContentRectForDrawContents.width(), -m_visibleContentRectForDrawContents.y() - m_visibleContentRectForDrawContents.height());
1260             matrix.scale(m_scaleFactor);
1261         } else
1262             matrix.setMatrix(m_scaleFactor, 0, 0, m_scaleFactor, -m_visibleContentRectForDrawContents.x(), -m_visibleContentRectForDrawContents.y());
1263         clipRect = IntRect(IntPoint(), m_visibleContentRectForDrawContents.size());
1264     }
1265 #else
1266     glViewport(0, 0, m_visibleContentRectForDrawContents.width(), m_visibleContentRectForDrawContents.height());
1267     matrix.setMatrix(m_scaleFactorForDrawContents, 0, 0, m_scaleFactorForDrawContents, -m_visibleContentRectForDrawContents.x(), -m_visibleContentRectForDrawContents.y());
1268     clipRect = IntRect(IntPoint(), m_visibleContentRectForDrawContents.size());
1269 #endif
1270
1271     float bgRed, bgGreen, bgBlue, bgAlpha;
1272     m_bgColor.getRGBA(bgRed, bgGreen, bgBlue, bgAlpha);
1273     glClearColor(bgRed, bgGreen, bgBlue, bgAlpha);
1274     glClear(GL_COLOR_BUFFER_BIT);
1275
1276     if (drawingArea()) {
1277         if (drawingArea()->layerTreeHostProxy()) {
1278             WebLayerTreeRenderer* renderer = drawingArea()->layerTreeHostProxy()->layerTreeRenderer();
1279             renderer->syncRemoteContent();
1280             renderer->paintToCurrentGLContext(matrix, 1.0f, clipRect);
1281         }
1282     }
1283
1284 #endif // #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1285
1286 }
1287
1288 void PageClientImpl::scaleImage(double scaleFactor, IntPoint scrollPosition, bool adjustToBoundary)
1289 {
1290 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1291     m_textSelection->hideHandlers();
1292 #endif
1293
1294     // Adjust scaleFactor.
1295 #if ENABLE(TIZEN_WEBKIT2_TEXT_ZOOM)
1296     if (!page()->pageGroup()->preferences()->textZoomEnabled())
1297         scaleFactor = adjustScaleWithViewport(scaleFactor);
1298 #else
1299     scaleFactor = adjustScaleWithViewport(scaleFactor);
1300 #endif
1301
1302     // Adjust scrollPosition not to exceed contents boundary.
1303     if (adjustToBoundary) {
1304         double scaleDifference = scaleFactor / this->scaleFactor();
1305         scrollPosition.scale(scaleDifference, scaleDifference);
1306         IntSize contentsSize = page()->contentsSize();
1307         contentsSize.scale(scaleFactor);
1308         if (scrollPosition.x() > contentsSize.width() - viewSize().width())
1309             scrollPosition.setX(contentsSize.width() - viewSize().width());
1310         if (scrollPosition.y() > contentsSize.height() - viewSize().height())
1311             scrollPosition.setY(contentsSize.height() - viewSize().height());
1312     }
1313
1314     scaleContents(scaleFactor, scrollPosition);
1315 }
1316
1317 void PageClientImpl::scaleContents(double scaleFactor, const IntPoint& origin)
1318 {
1319     scaleFactor = adjustScaleWithViewport(scaleFactor);
1320
1321     setVisibleContentRect(origin, scaleFactor, FloatPoint());
1322 }
1323
1324 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
1325 void PageClientImpl::setTargetSurface()
1326 {
1327     int width, height;
1328     evas_object_geometry_get(page()->viewWidget(), 0, 0, &width, &height);
1329     if (width == 0 || height == 0)
1330         return;
1331
1332     m_surface = evas_gl_surface_create(m_evasGL, m_config, width, height);
1333     if (!m_surface) {
1334         fprintf(stderr, "[%p] DrawingAreaProxyImpl::%s() - failed to create Evas_GL_Surface\n", this, __FUNCTION__);
1335         return;
1336     }
1337
1338     Evas_Native_Surface nativeSurface;
1339     evas_gl_native_surface_get(m_evasGL, m_surface, &nativeSurface);
1340     ewk_view_image_native_surface_set(page()->viewWidget(), &nativeSurface);
1341
1342 #if ENABLE(TIZEN_WEBKIT2_DIRECT_RENDERING)
1343     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_viewWidget));
1344     int angle = ecore_evas_rotation_get(ee);
1345     m_angle = angle;
1346     drawingArea()->setAngle(m_angle);
1347 #endif
1348 }
1349 #endif
1350
1351 #if ENABLE(TIZEN_WEBKIT2_TILED_SCROLLBAR)
1352 void PageClientImpl::createScrollbarIfNeeded(bool horizontalBar, bool verticalBar)
1353 {
1354     // create if needed.
1355     if (horizontalBar && !m_horizontalScrollbar) {
1356         m_horizontalScrollbar = MainFrameScrollbarEfl::createNativeScrollbar(m_viewWidget, HorizontalScrollbar);
1357         IntRect hBarRect(0, viewSize().height(), viewSize().width(), 0);
1358         m_horizontalScrollbar->setFrameRect(hBarRect);
1359     } else if (!horizontalBar && m_horizontalScrollbar)
1360         m_horizontalScrollbar = 0;
1361
1362     if (verticalBar && !m_verticalScrollbar) {
1363         m_verticalScrollbar = MainFrameScrollbarEfl::createNativeScrollbar(m_viewWidget, VerticalScrollbar);
1364         IntRect vBarRect(viewSize().width(), 0, 0, viewSize().height());
1365         m_verticalScrollbar->setFrameRect(vBarRect);
1366     } else if (!verticalBar && m_verticalScrollbar)
1367         m_verticalScrollbar = 0;
1368 }
1369
1370 void PageClientImpl::updateScrollbar(const WebCore::IntPoint& scrollPosition)
1371 {
1372     IntSize scaledContentsSize = m_page->contentsSize();
1373     scaledContentsSize.scale(scaleFactor());
1374
1375     bool newHasHorizontalScrollbar = false;
1376     bool newVerticalScrollbar = false;
1377     if (viewSize().width() < scaledContentsSize.width())
1378         newHasHorizontalScrollbar = true;
1379     if (viewSize().height() < scaledContentsSize.height())
1380         newVerticalScrollbar = true;
1381     createScrollbarIfNeeded(newHasHorizontalScrollbar, newVerticalScrollbar);
1382
1383     if (m_horizontalScrollbar) {
1384         m_horizontalScrollbar->setProportion(viewSize().width(), scaledContentsSize.width());
1385         m_horizontalScrollbar->setPosition(scrollPosition.x());
1386     }
1387     if (m_verticalScrollbar) {
1388         m_verticalScrollbar->setProportion(viewSize().height(), scaledContentsSize.height());
1389         m_verticalScrollbar->setPosition(scrollPosition.y());
1390     }
1391 }
1392
1393 void PageClientImpl::frameRectChanged()
1394 {
1395     if (m_horizontalScrollbar) {
1396         IntRect hBarRect(0, viewSize().height(), viewSize().width(), 0);
1397         m_horizontalScrollbar->setFrameRect(hBarRect);
1398     }
1399     if (m_verticalScrollbar) {
1400         IntRect vBarRect(viewSize().width(), 0, 0, viewSize().height());
1401         m_verticalScrollbar->setFrameRect(vBarRect);
1402     }
1403 }
1404 #endif
1405 #endif // ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1406
1407 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1408 void PageClientImpl::updateTextSelection()
1409 {
1410     m_textSelection->update();
1411 }
1412
1413 bool PageClientImpl::isTextSelectionEnable()
1414 {
1415     return m_textSelection->isTextSelectionEnable();
1416 }
1417
1418 void PageClientImpl::setIsTextSelectionEnable(bool isTextSelectionEnable)
1419 {
1420     m_textSelection->setIsTextSelectionEnable(isTextSelectionEnable);
1421 }
1422
1423 bool PageClientImpl::isTextSelectionDowned()
1424 {
1425     return m_textSelection->isTextSelectionDowned();
1426 }
1427
1428 bool PageClientImpl::isTextSelectionMode()
1429 {
1430     return m_textSelection->isTextSelectionMode();
1431 }
1432
1433 void PageClientImpl::setIsTextSelectionMode(bool isTextSelectionMode)
1434 {
1435     m_textSelection->setIsTextSelectionMode(isTextSelectionMode);
1436 }
1437
1438 void PageClientImpl::updateTextSelectionHandlesAndContextMenu(bool isShow)
1439 {
1440     if (m_textSelection->isTextSelectionMode())
1441         m_textSelection->updateHandlesAndContextMenu(isShow);
1442 }
1443
1444 void PageClientImpl::textSelectionDown(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside)
1445 {
1446     m_textSelection->textSelectionDown(point, isStartedTextSelectionFromOutside);
1447 }
1448
1449 void PageClientImpl::textSelectionMove(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside)
1450 {
1451     m_textSelection->textSelectionMove(point, isStartedTextSelectionFromOutside);
1452 }
1453
1454 void PageClientImpl::textSelectionUp(const WebCore::IntPoint& point)
1455 {
1456     m_textSelection->textSelectionUp(point);
1457 }
1458 #endif
1459
1460 #if ENABLE(TIZEN_WEBKIT_PASTEBOARD)
1461 void PageClientImpl::writeDataToClipboardWithType(const String& data, WebCore::Pasteboard::PasteboardDataType type)
1462 {
1463     ewk_view_write_data_to_clipboard_with_type(viewWidget(), data, type);
1464 }
1465
1466 void PageClientImpl::pasteWithClipboard()
1467 {
1468     ewk_view_paste_with_clipboard(viewWidget());
1469 }
1470 #endif
1471
1472 void PageClientImpl::suspendIfNeeded()
1473 {
1474     if (m_page->estimatedProgress() < 1.0) {
1475         m_suspendRequested = true;
1476         return;
1477     }
1478     m_suspendRequested = false;
1479
1480 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1481     setIsTextSelectionMode(false);
1482 #endif
1483
1484     suspendPainting();
1485     suspendJavaScriptAndResource();
1486
1487 #if ENABLE(TIZEN_NPAPI)
1488     suspendPlugin();
1489 #endif
1490 }
1491
1492 void PageClientImpl::resumeIfNeeded()
1493 {
1494     if (m_suspendRequested) {
1495         m_suspendRequested = false;
1496         return;
1497     }
1498     resumePainting();
1499     resumeJavaScriptAndResource();
1500
1501 #if ENABLE(TIZEN_NPAPI)
1502     resumePlugin();
1503 #endif
1504 }
1505
1506 #if ENABLE(TIZEN_NPAPI)
1507 void PageClientImpl::suspendPlugin()
1508 {
1509     if (!m_page->isValid())
1510         return;
1511
1512     m_page->process()->send(Messages::WebPage::SuspendPlugin(), m_page->pageID());
1513 }
1514
1515 void PageClientImpl::resumePlugin()
1516 {
1517     if (!m_page->isValid())
1518         return;
1519
1520     m_page->process()->send(Messages::WebPage::ResumePlugin(), m_page->pageID());
1521 }
1522 #endif
1523
1524 void PageClientImpl::suspendPainting()
1525 {
1526     if (!m_page->isValid() || m_suspendPainting)
1527         return;
1528
1529     m_page->process()->send(Messages::DrawingArea::SuspendPainting(), m_page->pageID());
1530     m_suspendPainting = true;
1531 }
1532
1533 void PageClientImpl::suspendJavaScriptAndResource()
1534 {
1535     if (!m_page->isValid() || m_suspendResource)
1536         return;
1537
1538     m_page->process()->send(Messages::WebPage::SuspendJavaScriptAndResources(), m_page->pageID());
1539     m_suspendResource = true;
1540 }
1541
1542 void PageClientImpl::resumePainting()
1543 {
1544     if (!m_page->isValid() || !m_suspendPainting)
1545         return;
1546
1547     m_page->process()->send(Messages::DrawingArea::ResumePainting(), m_page->pageID());
1548     m_suspendPainting = false;
1549 }
1550
1551 void PageClientImpl::resumeJavaScriptAndResource()
1552 {
1553     if (!m_page->isValid() || !m_suspendResource)
1554         return;
1555
1556     m_page->process()->send(Messages::WebPage::ResumeJavaScriptAndResources(), m_page->pageID());
1557     m_suspendResource = false;
1558 }
1559
1560 #if ENABLE(TIZEN_WEBKIT2_VIEW_VISIBILITY)
1561 void PageClientImpl::setIsVisible(bool isVisible)
1562 {
1563     m_isVisible = isVisible;
1564
1565     if (m_page)
1566         m_page->viewStateDidChange(WebPageProxy::ViewIsVisible);
1567 }
1568 #endif
1569
1570 #if ENABLE(TIZEN_REGISTER_PROTOCOL_HANDLER)
1571 void PageClientImpl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
1572 {
1573     ewkViewRegisterProtocolHandlers(m_viewWidget, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data(), title.utf8().data());
1574 }
1575 #endif
1576
1577 #if ENABLE(TIZEN_REGISTER_CONTENT_HANDLER)
1578 void PageClientImpl::registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title)
1579 {
1580     ewkViewRegisterContentHandlers(m_viewWidget, mimeType.utf8().data(), baseURL.utf8().data(), url.utf8().data(), title.utf8().data());
1581 }
1582 #endif
1583
1584 #if ENABLE(TIZEN_SUPPORT_WEBAPP_META_TAG)
1585 bool PageClientImpl::getStandaloneStatus()
1586 {
1587     return ewkViewGetStandaloneStatus(m_viewWidget);
1588 }
1589 #endif
1590
1591 #if ENABLE(TIZEN_VIBRATION)
1592 void PageClientImpl::vibrate(const unsigned long& time)
1593 {
1594     evas_object_smart_callback_call(viewWidget(), "vibration,vibrate", (void*)&time);
1595 }
1596
1597 void PageClientImpl::cancelVibration()
1598 {
1599     evas_object_smart_callback_call(viewWidget(), "vibration,cancel", 0);
1600 }
1601 #endif
1602
1603 #if ENABLE(SCREEN_ORIENTATION_SUPPORT) && ENABLE(TIZEN_SCREEN_ORIENTATION_SUPPORT)
1604 bool PageClientImpl::lockOrientation(int willLockOrientation)
1605 {
1606     return ewk_view_orientation_lock(m_viewWidget, willLockOrientation);
1607 }
1608
1609 void PageClientImpl::unlockOrientation()
1610 {
1611     ewk_view_orientation_unlock(m_viewWidget);
1612 }
1613 #endif
1614
1615 void PageClientImpl::didRenderFrame()
1616 {
1617     ewkViewFrameRendered(m_viewWidget);
1618 }
1619
1620 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE) && ENABLE(TIZEN_WEBKIT2_HIT_TEST)
1621 void PageClientImpl::findScrollableNode(IntPoint& point)
1622 {
1623     WebHitTestResult::Data hitTestResultData = page()->hitTestResultAtPoint(point, WebHitTestResult::HitTestModeNodeData);
1624     setIsScrollableNodeFocused(hitTestResultData.nodeData.isScrollableNodeFocused);
1625     if (hitTestResultData.nodeData.isScrollableNodeFocused)
1626         page()->drawingArea()->layerTreeHostProxy()->layerTreeRenderer()->setFocusedLayerID(hitTestResultData.nodeData.enclosingWebLayerID);
1627 }
1628 #endif
1629
1630 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1631 void PageClientImpl::didGetTextStyleStateForSelection(int underlineState, int italicState, int boldState)
1632 {
1633     ewkViewDidGetTextStyleStateForSelection(m_viewWidget, underlineState, italicState, boldState);
1634 }
1635 #endif
1636
1637 void PageClientImpl::didFindZoomableArea(const IntPoint& target, const IntRect& area)
1638 {
1639     ewk_view_zoomable_area_set(m_viewWidget, target, area);
1640 }
1641
1642 #endif // #if OS(TIZEN)
1643
1644 } // namespace WebKit