1/* 2 * Copyright (C) 2010 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 26#include "config.h" 27#include "MediaPlayerPrivateFullscreenWindow.h" 28 29#include "IntRect.h" 30#include "WebCoreInstanceHandle.h" 31#include <windows.h> 32 33#if USE(CG) 34#include <CoreGraphics/CGColor.h> 35#endif 36 37#if USE(CA) 38#include "CACFLayerTreeHost.h" 39#include "PlatformCALayer.h" 40#endif 41 42namespace WebCore { 43 44MediaPlayerPrivateFullscreenWindow::MediaPlayerPrivateFullscreenWindow(MediaPlayerPrivateFullscreenClient* client) 45 : m_client(client) 46 , m_hwnd(0) 47{ 48} 49 50MediaPlayerPrivateFullscreenWindow::~MediaPlayerPrivateFullscreenWindow() 51{ 52 if (!m_hwnd) 53 return; 54 55 ::DestroyWindow(m_hwnd); 56 ASSERT(!m_hwnd); 57} 58 59void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd) 60{ 61 static ATOM windowAtom; 62 static LPCWSTR windowClassName = L"MediaPlayerPrivateFullscreenWindowClass"; 63 if (!windowAtom) { 64 WNDCLASSEX wcex = {0}; 65 wcex.cbSize = sizeof(wcex); 66 wcex.style = CS_HREDRAW | CS_VREDRAW; 67 wcex.lpfnWndProc = staticWndProc; 68 wcex.hInstance = instanceHandle(); 69 wcex.lpszClassName = windowClassName; 70 windowAtom = ::RegisterClassEx(&wcex); 71 } 72 73 ASSERT(!m_hwnd); 74 75 MONITORINFO mi = {0}; 76 mi.cbSize = sizeof(MONITORINFO); 77 if (!GetMonitorInfo(MonitorFromWindow(parentHwnd, MONITOR_DEFAULTTONEAREST), &mi)) 78 return; 79 80 IntRect monitorRect = mi.rcMonitor; 81 82 ::CreateWindowExW(WS_EX_TOOLWINDOW, windowClassName, L"", WS_POPUP, 83 monitorRect.x(), monitorRect.y(), monitorRect.width(), monitorRect.height(), 84 parentHwnd, 0, instanceHandle(), this); 85 ASSERT(IsWindow(m_hwnd)); 86 87#if USE(CA) 88 if (m_layerTreeHost) 89 m_layerTreeHost->setWindow(m_hwnd); 90#endif 91 92 ::SetFocus(m_hwnd); 93} 94 95#if USE(CA) 96void MediaPlayerPrivateFullscreenWindow::setRootChildLayer(PassRefPtr<PlatformCALayer> rootChild) 97{ 98 if (m_rootChild == rootChild) 99 return; 100 101 if (m_rootChild) 102 m_rootChild->removeFromSuperlayer(); 103 104 m_rootChild = rootChild; 105 106 if (!m_rootChild) { 107 m_layerTreeHost = nullptr; 108 return; 109 } 110 111 if (!m_layerTreeHost) { 112 m_layerTreeHost = CACFLayerTreeHost::create(); 113 if (m_hwnd) { 114 m_layerTreeHost->setWindow(m_hwnd); 115 m_layerTreeHost->createRenderer(); 116 } 117 } 118 119 m_layerTreeHost->setRootChildLayer(m_rootChild.get()); 120 PlatformCALayer* rootLayer = m_rootChild->rootLayer(); 121 CGRect rootBounds = m_rootChild->rootLayer()->bounds(); 122 m_rootChild->setPosition(rootBounds.origin); 123 m_rootChild->setBounds(FloatRect(FloatPoint(), FloatSize(rootBounds.size))); 124 m_rootChild->setBackgroundColor(CGColorGetConstantColor(kCGColorBlack)); 125#ifndef NDEBUG 126 RetainPtr<CGColorRef> redColor = adoptCF(CGColorCreateGenericRGB(1, 0, 0, 1)); 127 rootLayer->setBackgroundColor(redColor.get()); 128#else 129 rootLayer->setBackgroundColor(CGColorGetConstantColor(kCGColorBlack)); 130#endif 131} 132#endif 133 134LRESULT MediaPlayerPrivateFullscreenWindow::staticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 135{ 136 LONG_PTR longPtr = GetWindowLongPtr(hWnd, GWLP_USERDATA); 137 138 if (!longPtr && message == WM_CREATE) { 139 LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); 140 longPtr = reinterpret_cast<LONG_PTR>(lpcs->lpCreateParams); 141 ::SetWindowLongPtr(hWnd, GWLP_USERDATA, longPtr); 142 } 143 144 if (MediaPlayerPrivateFullscreenWindow* window = reinterpret_cast<MediaPlayerPrivateFullscreenWindow*>(longPtr)) 145 return window->wndProc(hWnd, message, wParam, lParam); 146 147 return ::DefWindowProc(hWnd, message, wParam, lParam); 148} 149 150LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 151{ 152 LRESULT lResult = 0; 153 switch (message) { 154 case WM_CREATE: 155 m_hwnd = hWnd; 156 break; 157 case WM_DESTROY: 158 m_hwnd = 0; 159#if USE(CA) 160 if (m_layerTreeHost) 161 m_layerTreeHost->setWindow(0); 162#endif 163 break; 164 case WM_WINDOWPOSCHANGED: 165 { 166 LPWINDOWPOS wp = reinterpret_cast<LPWINDOWPOS>(lParam); 167 if (wp->flags & SWP_NOSIZE) 168 break; 169#if USE(CA) 170 if (m_layerTreeHost) { 171 m_layerTreeHost->resize(); 172 PlatformCALayer* rootLayer = m_rootChild->rootLayer(); 173 CGRect rootBounds = m_rootChild->rootLayer()->bounds(); 174 m_rootChild->setPosition(rootBounds.origin); 175 m_rootChild->setBounds(FloatRect(FloatPoint(), FloatSize(rootBounds.size))); 176 m_rootChild->setNeedsLayout(); 177 } 178#endif 179 } 180 break; 181 case WM_PAINT: 182#if USE(CA) 183 if (m_layerTreeHost) { 184 m_layerTreeHost->paint(); 185 ::ValidateRect(m_hwnd, 0); 186 } else 187#endif 188 { 189 PAINTSTRUCT ps; 190 HDC hdc = ::BeginPaint(m_hwnd, &ps); 191 ::FillRect(hdc, &ps.rcPaint, (HBRUSH)::GetStockObject(BLACK_BRUSH)); 192 ::EndPaint(m_hwnd, &ps); 193 } 194 break; 195 case WM_PRINTCLIENT: 196 { 197 RECT clientRect; 198 HDC context = (HDC)wParam; 199 ::GetClientRect(m_hwnd, &clientRect); 200 ::FillRect(context, &clientRect, (HBRUSH)::GetStockObject(BLACK_BRUSH)); 201 } 202 } 203 if (m_client) 204 lResult = m_client->fullscreenClientWndProc(hWnd, message, wParam, lParam); 205 206 return lResult; 207} 208 209} 210