summaryrefslogtreecommitdiffstats
path: root/WebKit/win/FullscreenVideoController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/win/FullscreenVideoController.cpp')
-rw-r--r--WebKit/win/FullscreenVideoController.cpp151
1 files changed, 120 insertions, 31 deletions
diff --git a/WebKit/win/FullscreenVideoController.cpp b/WebKit/win/FullscreenVideoController.cpp
index dbfc794..5f9b959 100644
--- a/WebKit/win/FullscreenVideoController.cpp
+++ b/WebKit/win/FullscreenVideoController.cpp
@@ -30,12 +30,16 @@
#include "FullscreenVideoController.h"
#include "WebKitDLL.h"
+#include "WebView.h"
#include <ApplicationServices/ApplicationServices.h>
#include <WebCore/BitmapInfo.h>
+#include <WebCore/Chrome.h>
#include <WebCore/Font.h>
#include <WebCore/FontSelector.h>
#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
#include <WebCore/TextRun.h>
+#include <WebCore/WKCACFLayer.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <windowsx.h>
#include <wtf/StdLibExtras.h>
@@ -112,7 +116,7 @@ HUDButton::HUDButton(HUDButtonType type, const IntPoint& position)
void HUDButton::draw(GraphicsContext& context)
{
Image* image = (m_showAltButton && m_buttonImageAlt) ? m_buttonImageAlt.get() : m_buttonImage.get();
- context.drawImage(image, DeviceColorSpace, m_rect.location());
+ context.drawImage(image, ColorSpaceDeviceRGB, m_rect.location());
}
HUDSlider::HUDSlider(HUDSliderButtonShape shape, int buttonSize, const IntRect& rect)
@@ -128,11 +132,11 @@ void HUDSlider::draw(GraphicsContext& context)
{
// Draw gutter
IntSize radius(m_rect.height() / 2, m_rect.height() / 2);
- context.fillRoundedRect(m_rect, radius, radius, radius, radius, Color(sliderGutterColor), DeviceColorSpace);
+ context.fillRoundedRect(m_rect, radius, radius, radius, radius, Color(sliderGutterColor), ColorSpaceDeviceRGB);
// Draw button
- context.setStrokeColor(Color(sliderButtonColor), DeviceColorSpace);
- context.setFillColor(Color(sliderButtonColor), DeviceColorSpace);
+ context.setStrokeColor(Color(sliderButtonColor), ColorSpaceDeviceRGB);
+ context.setFillColor(Color(sliderButtonColor), ColorSpaceDeviceRGB);
if (m_buttonShape == RoundButton) {
context.drawEllipse(IntRect(m_rect.location().x() + m_buttonPosition, m_rect.location().y() - (m_buttonSize - m_rect.height()) / 2, m_buttonSize, m_buttonSize));
@@ -169,9 +173,53 @@ void HUDSlider::drag(const IntPoint& point, bool start)
m_buttonPosition = max(0, min(m_rect.width() - m_buttonSize, point.x() - m_dragStartOffset));
}
+#if USE(ACCELERATED_COMPOSITING)
+class FullscreenVideoController::LayoutClient : public WKCACFLayerLayoutClient {
+public:
+ LayoutClient(FullscreenVideoController* parent);
+ void layoutSublayersOfLayer(WKCACFLayer* layer);
+
+ FullscreenVideoController* m_parent;
+};
+
+FullscreenVideoController::LayoutClient::LayoutClient(FullscreenVideoController* parent)
+ : m_parent(parent)
+{
+}
+
+void FullscreenVideoController::LayoutClient::layoutSublayersOfLayer(WKCACFLayer* layer)
+{
+ ASSERT_ARG(layer, layer == m_parent->m_rootChild);
+
+ HTMLMediaElement* mediaElement = m_parent->m_mediaElement.get();
+ if (!mediaElement)
+ return;
+
+ WKCACFLayer* videoLayer = mediaElement->platformLayer();
+ if (!videoLayer || videoLayer->superlayer() != layer)
+ return;
+
+ FloatRect layerBounds = layer->bounds();
+
+ FloatSize videoSize = mediaElement->player()->naturalSize();
+ float scaleFactor;
+ if (videoSize.aspectRatio() > layerBounds.size().aspectRatio())
+ scaleFactor = layerBounds.width() / videoSize.width();
+ else
+ scaleFactor = layerBounds.height() / videoSize.height();
+ videoSize.scale(scaleFactor);
+
+ // Calculate the centered position based on the videoBounds and layerBounds:
+ FloatPoint videoPosition;
+ FloatPoint videoOrigin;
+ videoOrigin.setX((layerBounds.width() - videoSize.width()) * 0.5);
+ videoOrigin.setY((layerBounds.height() - videoSize.height()) * 0.5);
+ videoLayer->setFrame(FloatRect(videoOrigin, videoSize));
+}
+#endif
+
FullscreenVideoController::FullscreenVideoController()
: m_hudWindow(0)
- , m_videoWindow(0)
, m_playPauseButton(HUDButton::PlayPauseButton, IntPoint((windowWidth - buttonSize) / 2, marginTop))
, m_timeSliderButton(HUDButton::TimeSliderButton, IntPoint(0, 0))
, m_volumeUpButton(HUDButton::VolumeUpButton, IntPoint(margin + buttonMiniSize + volumeSliderWidth + buttonMiniSize / 2, marginTop + (buttonSize - buttonMiniSize) / 2))
@@ -183,18 +231,22 @@ FullscreenVideoController::FullscreenVideoController()
, m_hitWidget(0)
, m_movingWindow(false)
, m_timer(this, &FullscreenVideoController::timerFired)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_rootChild(WKCACFLayer::create(WKCACFLayer::Layer))
+ , m_layoutClient(new LayoutClient(this))
+#endif
+ , m_fullscreenWindow(new MediaPlayerPrivateFullscreenWindow(this))
{
+#if USE(ACCELERATED_COMPOSITING)
+ m_rootChild->setLayoutClient(m_layoutClient.get());
+#endif
}
FullscreenVideoController::~FullscreenVideoController()
{
- if (movie())
- movie()->exitFullscreen();
-}
-
-QTMovieWin* FullscreenVideoController::movie() const
-{
- return m_mediaElement ? reinterpret_cast<QTMovieWin*>(m_mediaElement->platformMedia().qtMovie) : 0;
+#if USE(ACCELERATED_COMPOSITING)
+ m_rootChild->setLayoutClient(0);
+#endif
}
void FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement)
@@ -211,13 +263,24 @@ void FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement)
void FullscreenVideoController::enterFullscreen()
{
- if (!movie())
+ if (!m_mediaElement)
return;
- m_videoWindow = movie()->enterFullscreen(this);
+ WebView* webView = kit(m_mediaElement->document()->page());
+ HWND parentHwnd = webView ? webView->viewWindow() : 0;
+
+ m_fullscreenWindow->createWindow(parentHwnd);
+#if USE(ACCELERATED_COMPOSITING)
+ m_fullscreenWindow->setRootChildLayer(m_rootChild);
+
+ WKCACFLayer* videoLayer = m_mediaElement->platformLayer();
+ m_rootChild->addSublayer(videoLayer);
+ m_rootChild->setNeedsLayout();
+ m_rootChild->setGeometryFlipped(1);
+#endif
RECT windowRect;
- GetClientRect(m_videoWindow, &windowRect);
+ GetClientRect(m_fullscreenWindow->hwnd(), &windowRect);
m_fullscreenSize.setWidth(windowRect.right - windowRect.left);
m_fullscreenSize.setHeight(windowRect.bottom - windowRect.top);
@@ -226,13 +289,24 @@ void FullscreenVideoController::enterFullscreen()
void FullscreenVideoController::exitFullscreen()
{
- if (movie())
- movie()->exitFullscreen();
-
- m_videoWindow = 0;
SetWindowLongPtr(m_hudWindow, 0, 0);
- DestroyWindow(m_hudWindow);
+
+ if (m_fullscreenWindow)
+ m_fullscreenWindow = 0;
+
+ ASSERT(!IsWindow(m_hudWindow));
m_hudWindow = 0;
+
+ // We previously ripped the mediaElement's platform layer out
+ // of its orginial layer tree to display it in our fullscreen
+ // window. Now, we need to get the layer back in its original
+ // tree.
+ //
+ // As a side effect of setting the player to invisible/visible,
+ // the player's layer will be recreated, and will be picked up
+ // the next time the layer tree is synched.
+ m_mediaElement->player()->setVisible(0);
+ m_mediaElement->player()->setVisible(1);
}
bool FullscreenVideoController::canPlay() const
@@ -301,6 +375,9 @@ LRESULT FullscreenVideoController::fullscreenClientWndProc(HWND wnd, UINT messag
case WM_CHAR:
onChar(wParam);
break;
+ case WM_KEYDOWN:
+ onKeyDown(wParam);
+ break;
case WM_LBUTTONDOWN:
onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
@@ -357,7 +434,7 @@ void FullscreenVideoController::createHUDWindow()
// Dirty the window so the HUD draws
RECT clearRect = { m_hudPosition.x(), m_hudPosition.y(), m_hudPosition.x() + windowWidth, m_hudPosition.y() + windowHeight };
- InvalidateRect(m_videoWindow, &clearRect, true);
+ InvalidateRect(m_fullscreenWindow->hwnd(), &clearRect, true);
m_playPauseButton.setShowAltButton(!canPlay());
m_volumeSlider.setValue(volume());
@@ -368,9 +445,9 @@ void FullscreenVideoController::createHUDWindow()
registerHUDWindowClass();
- m_hudWindow = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
+ m_hudWindow = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,
fullscreenVideeoHUDWindowClassName, 0, WS_POPUP | WS_VISIBLE,
- m_hudPosition.x(), m_hudPosition.y(), 0, 0, 0, 0, gInstance, 0);
+ m_hudPosition.x(), m_hudPosition.y(), 0, 0, m_fullscreenWindow->hwnd(), 0, gInstance, 0);
ASSERT(::IsWindow(m_hudWindow));
SetWindowLongPtr(m_hudWindow, 0, reinterpret_cast<LONG_PTR>(this));
@@ -400,7 +477,7 @@ void FullscreenVideoController::draw()
HDC windowDC = GetDC(m_hudWindow);
HDC bitmapDC = CreateCompatibleDC(windowDC);
::ReleaseDC(m_hudWindow, windowDC);
- SelectObject(bitmapDC, m_bitmap.get());
+ HGDIOBJ oldBitmap = SelectObject(bitmapDC, m_bitmap.get());
GraphicsContext context(bitmapDC, true);
@@ -412,9 +489,9 @@ void FullscreenVideoController::draw()
IntSize innerRadius(borderRadius - borderThickness, borderRadius - borderThickness);
IntRect innerRect(borderThickness, borderThickness, windowWidth - borderThickness * 2, windowHeight - borderThickness * 2);
- context.fillRoundedRect(outerRect, outerRadius, outerRadius, outerRadius, outerRadius, Color(borderColor), DeviceColorSpace);
+ context.fillRoundedRect(outerRect, outerRadius, outerRadius, outerRadius, outerRadius, Color(borderColor), ColorSpaceDeviceRGB);
context.setCompositeOperation(CompositeCopy);
- context.fillRoundedRect(innerRect, innerRadius, innerRadius, innerRadius, innerRadius, Color(backgroundColor), DeviceColorSpace);
+ context.fillRoundedRect(innerRect, innerRadius, innerRadius, innerRadius, innerRadius, Color(backgroundColor), ColorSpaceDeviceRGB);
// Draw the widgets
m_playPauseButton.draw(context);
@@ -449,13 +526,13 @@ void FullscreenVideoController::draw()
// Left string
s = timeToString(currentTime());
TextRun leftText(s);
- context.setFillColor(Color(textColor), DeviceColorSpace);
+ context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
context.drawText(font, leftText, IntPoint(windowWidth / 2 - timeSliderWidth / 2 - margin - font.width(leftText), windowHeight - margin - sliderHeight / 2 + font.height() / 4));
// Right string
s = timeToString(currentTime() - duration());
TextRun rightText(s);
- context.setFillColor(Color(textColor), DeviceColorSpace);
+ context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
context.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + font.height() / 4));
// Copy to the window
@@ -467,6 +544,7 @@ void FullscreenVideoController::draw()
context.restore();
+ ::SelectObject(bitmapDC, oldBitmap);
::DeleteDC(bitmapDC);
}
@@ -481,6 +559,9 @@ LRESULT FullscreenVideoController::hudWndProc(HWND wnd, UINT message, WPARAM wPa
case WM_CHAR:
controller->onChar(wParam);
break;
+ case WM_KEYDOWN:
+ controller->onKeyDown(wParam);
+ break;
case WM_LBUTTONDOWN:
controller->onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
@@ -504,6 +585,14 @@ void FullscreenVideoController::onChar(int c)
togglePlay();
}
+void FullscreenVideoController::onKeyDown(int virtualKey)
+{
+ if (virtualKey == VK_ESCAPE) {
+ if (m_mediaElement)
+ m_mediaElement->exitFullscreen();
+ }
+}
+
void FullscreenVideoController::timerFired(Timer<FullscreenVideoController>*)
{
// Update the time slider
@@ -513,7 +602,7 @@ void FullscreenVideoController::timerFired(Timer<FullscreenVideoController>*)
void FullscreenVideoController::onMouseDown(const IntPoint& point)
{
- IntPoint convertedPoint(fullScreenToHUDCoordinates(point));
+ IntPoint convertedPoint(fullscreenToHUDCoordinates(point));
// Don't bother hit testing if we're outside the bounds of the window
if (convertedPoint.x() < 0 || convertedPoint.x() >= windowWidth || convertedPoint.y() < 0 || convertedPoint.y() >= windowHeight)
@@ -552,7 +641,7 @@ void FullscreenVideoController::onMouseDown(const IntPoint& point)
void FullscreenVideoController::onMouseMove(const IntPoint& point)
{
- IntPoint convertedPoint(fullScreenToHUDCoordinates(point));
+ IntPoint convertedPoint(fullscreenToHUDCoordinates(point));
if (m_hitWidget) {
m_hitWidget->drag(convertedPoint, false);
@@ -567,7 +656,7 @@ void FullscreenVideoController::onMouseMove(const IntPoint& point)
void FullscreenVideoController::onMouseUp(const IntPoint& point)
{
- IntPoint convertedPoint(fullScreenToHUDCoordinates(point));
+ IntPoint convertedPoint(fullscreenToHUDCoordinates(point));
m_movingWindow = false;
if (m_hitWidget) {