1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
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#include "config.h"
26#include "WebFullScreenManager.h"
27
28#if ENABLE(FULLSCREEN_API)
29
30#include "Connection.h"
31#include "WebCoreArgumentCoders.h"
32#include "WebFrame.h"
33#include "WebFullScreenManagerProxyMessages.h"
34#include "WebPage.h"
35#include <WebCore/Color.h>
36#include <WebCore/Element.h>
37#include <WebCore/Frame.h>
38#include <WebCore/FrameView.h>
39#include <WebCore/Page.h>
40#include <WebCore/RenderLayer.h>
41#include <WebCore/RenderLayerBacking.h>
42#include <WebCore/RenderObject.h>
43#include <WebCore/RenderView.h>
44#include <WebCore/Settings.h>
45
46using namespace WebCore;
47
48namespace WebKit {
49
50static IntRect screenRectOfContents(Element* element)
51{
52    ASSERT(element);
53#if USE(ACCELERATED_COMPOSITING)
54    if (element->renderer() && element->renderer()->hasLayer() && element->renderer()->enclosingLayer()->isComposited()) {
55        FloatQuad contentsBox = static_cast<FloatRect>(element->renderer()->enclosingLayer()->backing()->contentsBox());
56        contentsBox = element->renderer()->localToAbsoluteQuad(contentsBox);
57        return element->renderer()->view()->frameView()->contentsToScreen(contentsBox.enclosingBoundingBox());
58    }
59#endif
60    return element->screenRect();
61}
62
63PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page)
64{
65    return adoptRef(new WebFullScreenManager(page));
66}
67
68WebFullScreenManager::WebFullScreenManager(WebPage* page)
69    : m_page(page)
70{
71}
72
73WebFullScreenManager::~WebFullScreenManager()
74{
75}
76
77WebCore::Element* WebFullScreenManager::element()
78{
79    return m_element.get();
80}
81
82void WebFullScreenManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder)
83{
84    didReceiveWebFullScreenManagerMessage(connection, decoder);
85}
86
87bool WebFullScreenManager::supportsFullScreen(bool withKeyboard)
88{
89    if (!m_page->corePage()->settings()->fullScreenEnabled())
90        return false;
91
92    return m_page->injectedBundleFullScreenClient().supportsFullScreen(m_page.get(), withKeyboard);
93}
94
95void WebFullScreenManager::enterFullScreenForElement(WebCore::Element* element)
96{
97    ASSERT(element);
98    m_element = element;
99    m_initialFrame = screenRectOfContents(m_element.get());
100    m_page->injectedBundleFullScreenClient().enterFullScreenForElement(m_page.get(), element);
101}
102
103void WebFullScreenManager::exitFullScreenForElement(WebCore::Element* element)
104{
105    m_page->injectedBundleFullScreenClient().exitFullScreenForElement(m_page.get(), element);
106}
107
108void WebFullScreenManager::willEnterFullScreen()
109{
110    ASSERT(m_element);
111    m_element->document()->webkitWillEnterFullScreenForElement(m_element.get());
112    m_page->hidePageBanners();
113    m_element->document()->updateLayout();
114    m_page->forceRepaintWithoutCallback();
115    m_finalFrame = screenRectOfContents(m_element.get());
116    m_page->injectedBundleFullScreenClient().beganEnterFullScreen(m_page.get(), m_initialFrame, m_finalFrame);
117}
118
119void WebFullScreenManager::didEnterFullScreen()
120{
121    ASSERT(m_element);
122    m_element->document()->webkitDidEnterFullScreenForElement(m_element.get());
123}
124
125void WebFullScreenManager::willExitFullScreen()
126{
127    ASSERT(m_element);
128    m_finalFrame = screenRectOfContents(m_element.get());
129    m_element->document()->webkitWillExitFullScreenForElement(m_element.get());
130    m_page->showPageBanners();
131    m_page->injectedBundleFullScreenClient().beganExitFullScreen(m_page.get(), m_finalFrame, m_initialFrame);
132}
133
134void WebFullScreenManager::didExitFullScreen()
135{
136    ASSERT(m_element);
137    m_element->document()->webkitDidExitFullScreenForElement(m_element.get());
138}
139
140void WebFullScreenManager::setAnimatingFullScreen(bool animating)
141{
142    ASSERT(m_element);
143    m_element->document()->setAnimatingFullScreen(animating);
144}
145
146void WebFullScreenManager::requestExitFullScreen()
147{
148    ASSERT(m_element);
149    m_element->document()->webkitCancelFullScreen();
150}
151
152void WebFullScreenManager::close()
153{
154    m_page->injectedBundleFullScreenClient().closeFullScreen(m_page.get());
155}
156
157void WebFullScreenManager::saveScrollPosition()
158{
159    m_scrollPosition = m_page->corePage()->mainFrame()->view()->scrollPosition();
160}
161
162void WebFullScreenManager::restoreScrollPosition()
163{
164    m_page->corePage()->mainFrame()->view()->setScrollPosition(m_scrollPosition);
165}
166
167} // namespace WebKit
168
169#endif // ENABLE(FULLSCREEN_API)
170