| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. | |
| 3 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | |
| 4 * | |
| 5 * Redistribution and use in source and binary forms, with or without | |
| 6 * modification, are permitted provided that the following conditions | |
| 7 * are met: | |
| 8 * 1. Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 * notice, this list of conditions and the following disclaimer in the | |
| 12 * documentation and/or other materials provided with the distribution. | |
| 13 * | |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
| 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 25 */ | |
| 26 | |
| 27 #include "config.h" | |
| 28 | |
| 29 #if ENABLE(FULLSCREEN_API) | |
| 30 | |
| 31 #include "FullScreenController.h" | |
| 32 | |
| 33 #include "Element.h" | |
| 34 #include "FullScreenControllerClient.h" | |
| 35 #include "IntRect.h" | |
| 36 #include "MediaPlayerPrivateFullscreenWindow.h" | |
| 37 #include "Timer.h" | |
| 38 #include "WebCoreInstanceHandle.h" | |
| 39 #include <wtf/RefPtr.h> | |
| 40 | |
| 41 using namespace WebCore; | |
| 42 | |
| 43 static const int kFullScreenAnimationDuration = 500; // milliseconds | |
| 44 | |
| 45 class FullScreenController::Private : public MediaPlayerPrivateFullscreenClient
{ | |
| 46 public: | |
| 47 Private(FullScreenController* controller, FullScreenControllerClient* client
) | |
| 48 : m_controller(controller) | |
| 49 , m_client(client) | |
| 50 , m_originalHost(0) | |
| 51 , m_isFullScreen(false) | |
| 52 , m_isEnteringFullScreen(false) | |
| 53 , m_isExitingFullScreen(false) | |
| 54 { | |
| 55 } | |
| 56 virtual ~Private() { } | |
| 57 | |
| 58 virtual LRESULT fullscreenClientWndProc(HWND, UINT, WPARAM, LPARAM); | |
| 59 | |
| 60 FullScreenController* m_controller; | |
| 61 FullScreenControllerClient* m_client; | |
| 62 OwnPtr<MediaPlayerPrivateFullscreenWindow> m_fullScreenWindow; | |
| 63 OwnPtr<MediaPlayerPrivateFullscreenWindow> m_backgroundWindow; | |
| 64 IntRect m_fullScreenFrame; | |
| 65 IntRect m_originalFrame; | |
| 66 HWND m_originalHost; | |
| 67 bool m_isFullScreen; | |
| 68 bool m_isEnteringFullScreen; | |
| 69 bool m_isExitingFullScreen; | |
| 70 }; | |
| 71 | |
| 72 LRESULT FullScreenController::Private::fullscreenClientWndProc(HWND hwnd, UINT m
sg, WPARAM wParam, LPARAM lParam) | |
| 73 { | |
| 74 LRESULT lResult = 0; | |
| 75 | |
| 76 switch (msg) { | |
| 77 case WM_MOVE: | |
| 78 m_fullScreenFrame.setX(LOWORD(lParam)); | |
| 79 m_fullScreenFrame.setY(HIWORD(lParam)); | |
| 80 break; | |
| 81 case WM_SIZE: | |
| 82 m_fullScreenFrame.setWidth(LOWORD(lParam)); | |
| 83 m_fullScreenFrame.setHeight(HIWORD(lParam)); | |
| 84 if (m_client->fullScreenClientWindow()) | |
| 85 ::SetWindowPos(m_client->fullScreenClientWindow(), 0, 0, 0, m_fullSc
reenFrame.width(), m_fullScreenFrame.height(), SWP_NOREPOSITION | SWP_NOMOVE); | |
| 86 break; | |
| 87 case WM_ACTIVATE: | |
| 88 // Because m_fullScreenWindow is a topmost window, we need to exit full
screen explicitly when it's deactivated. | |
| 89 if (!wParam && m_fullScreenWindow && (hwnd == m_fullScreenWindow->hwnd()
)) | |
| 90 m_controller->exitFullScreen(); | |
| 91 break; | |
| 92 case WM_KEYDOWN: | |
| 93 if (wParam == VK_ESCAPE) { | |
| 94 m_controller->exitFullScreen(); | |
| 95 break; | |
| 96 } | |
| 97 // Fall through. | |
| 98 default: | |
| 99 lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); | |
| 100 } | |
| 101 | |
| 102 return lResult; | |
| 103 } | |
| 104 | |
| 105 FullScreenController::FullScreenController(FullScreenControllerClient* client) | |
| 106 : m_private(adoptPtr(new FullScreenController::Private(this, client))) | |
| 107 { | |
| 108 ASSERT_ARG(client, client); | |
| 109 } | |
| 110 | |
| 111 FullScreenController::~FullScreenController() | |
| 112 { | |
| 113 } | |
| 114 | |
| 115 bool FullScreenController::isFullScreen() const | |
| 116 { | |
| 117 return m_private->m_isFullScreen; | |
| 118 } | |
| 119 | |
| 120 void FullScreenController::enterFullScreen() | |
| 121 { | |
| 122 if (m_private->m_isFullScreen || m_private->m_isEnteringFullScreen) | |
| 123 return; | |
| 124 m_private->m_isFullScreen = true; | |
| 125 m_private->m_isEnteringFullScreen = true; | |
| 126 | |
| 127 m_private->m_originalHost = m_private->m_client->fullScreenClientParentWindo
w(); | |
| 128 RECT originalFrame = {0, 0, 0, 0}; | |
| 129 ::GetClientRect(m_private->m_client->fullScreenClientWindow(), &originalFram
e); | |
| 130 ::MapWindowPoints(m_private->m_client->fullScreenClientWindow(), m_private->
m_originalHost, reinterpret_cast<LPPOINT>(&originalFrame), 2); | |
| 131 m_private->m_originalFrame = originalFrame; | |
| 132 | |
| 133 ASSERT(!m_private->m_backgroundWindow); | |
| 134 m_private->m_backgroundWindow = adoptPtr(new MediaPlayerPrivateFullscreenWin
dow(m_private.get())); | |
| 135 m_private->m_backgroundWindow->createWindow(0); | |
| 136 ::AnimateWindow(m_private->m_backgroundWindow->hwnd(), kFullScreenAnimationD
uration, AW_BLEND | AW_ACTIVATE); | |
| 137 | |
| 138 m_private->m_client->fullScreenClientWillEnterFullScreen(); | |
| 139 ASSERT(!m_private->m_fullScreenWindow); | |
| 140 m_private->m_fullScreenWindow = adoptPtr(new MediaPlayerPrivateFullscreenWin
dow(m_private.get())); | |
| 141 ASSERT(m_private->m_fullScreenWindow); | |
| 142 m_private->m_fullScreenWindow->createWindow(0); | |
| 143 | |
| 144 m_private->m_client->fullScreenClientSetParentWindow(m_private->m_fullScreen
Window->hwnd()); | |
| 145 | |
| 146 IntRect viewFrame(IntPoint(), m_private->m_fullScreenFrame.size()); | |
| 147 ::SetWindowPos(m_private->m_fullScreenWindow->hwnd(), HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | |
| 148 ::SetWindowPos(m_private->m_client->fullScreenClientWindow(), HWND_TOP, 0, 0
, viewFrame.width(), viewFrame.height(), SWP_NOACTIVATE); | |
| 149 | |
| 150 m_private->m_client->fullScreenClientDidEnterFullScreen(); | |
| 151 m_private->m_client->fullScreenClientForceRepaint(); | |
| 152 } | |
| 153 | |
| 154 void FullScreenController::enterFullScreenRepaintCompleted() | |
| 155 { | |
| 156 if (!m_private->m_isEnteringFullScreen) | |
| 157 return; | |
| 158 m_private->m_isEnteringFullScreen = false; | |
| 159 | |
| 160 // Normally, when the background fullscreen window is animated in, the Windo
ws taskbar will be hidden, but this doesn't always work for some reason. | |
| 161 // Setting the real fullscreen window to be a topmost window will force the
taskbar to be hidden when we call AnimateWindow() below if it wasn't before. | |
| 162 ::SetWindowPos(m_private->m_fullScreenWindow->hwnd(), HWND_TOPMOST, 0, 0, 0,
0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | |
| 163 ::AnimateWindow(m_private->m_fullScreenWindow->hwnd(), kFullScreenAnimationD
uration, AW_BLEND | AW_ACTIVATE); | |
| 164 } | |
| 165 | |
| 166 void FullScreenController::exitFullScreen() | |
| 167 { | |
| 168 if (!m_private->m_isFullScreen || m_private->m_isExitingFullScreen) | |
| 169 return; | |
| 170 m_private->m_isFullScreen = false; | |
| 171 m_private->m_isExitingFullScreen = true; | |
| 172 | |
| 173 ::AnimateWindow(m_private->m_fullScreenWindow->hwnd(), kFullScreenAnimationD
uration, AW_HIDE | AW_BLEND); | |
| 174 | |
| 175 m_private->m_client->fullScreenClientWillExitFullScreen(); | |
| 176 m_private->m_client->fullScreenClientSetParentWindow(m_private->m_originalHo
st); | |
| 177 m_private->m_fullScreenWindow = nullptr; | |
| 178 | |
| 179 ::SetWindowPos(m_private->m_client->fullScreenClientWindow(), 0, m_private->
m_originalFrame.x(), m_private->m_originalFrame.y(), m_private->m_originalFrame.
width(), m_private->m_originalFrame.height(), SWP_NOACTIVATE | SWP_NOZORDER); | |
| 180 | |
| 181 m_private->m_client->fullScreenClientDidExitFullScreen(); | |
| 182 m_private->m_client->fullScreenClientForceRepaint(); | |
| 183 } | |
| 184 | |
| 185 void FullScreenController::exitFullScreenRepaintCompleted() | |
| 186 { | |
| 187 if (!m_private->m_isExitingFullScreen) | |
| 188 return; | |
| 189 m_private->m_isExitingFullScreen = false; | |
| 190 | |
| 191 ASSERT(m_private->m_backgroundWindow); | |
| 192 ::AnimateWindow(m_private->m_backgroundWindow->hwnd(), kFullScreenAnimationD
uration, AW_HIDE | AW_BLEND); | |
| 193 m_private->m_backgroundWindow = nullptr; | |
| 194 } | |
| 195 | |
| 196 void FullScreenController::repaintCompleted() | |
| 197 { | |
| 198 if (m_private->m_isEnteringFullScreen) | |
| 199 enterFullScreenRepaintCompleted(); | |
| 200 else if (m_private->m_isExitingFullScreen) | |
| 201 exitFullScreenRepaintCompleted(); | |
| 202 } | |
| 203 | |
| 204 void FullScreenController::close() | |
| 205 { | |
| 206 if (!m_private->m_isFullScreen) | |
| 207 return; | |
| 208 m_private->m_isFullScreen = false; | |
| 209 | |
| 210 m_private->m_client->fullScreenClientWillExitFullScreen(); | |
| 211 m_private->m_client->fullScreenClientSetParentWindow(m_private->m_originalHo
st); | |
| 212 m_private->m_fullScreenWindow = nullptr; | |
| 213 | |
| 214 m_private->m_client->fullScreenClientDidExitFullScreen(); | |
| 215 ::SetWindowPos(m_private->m_client->fullScreenClientWindow(), 0, m_private->
m_originalFrame.x(), m_private->m_originalFrame.y(), m_private->m_originalFrame.
width(), m_private->m_originalFrame.height(), SWP_NOACTIVATE | SWP_NOZORDER); | |
| 216 ::RedrawWindow(m_private->m_client->fullScreenClientWindow(), 0, 0, RDW_INVA
LIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN); | |
| 217 m_private->m_backgroundWindow = nullptr; | |
| 218 } | |
| 219 #endif | |
| OLD | NEW |