[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
cmarrin at apple.com
cmarrin at apple.com
Wed Jan 20 22:17:38 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit dd1b9fb8f29a1ab0aac3f642ad04eb26ec281cdc
Author: cmarrin at apple.com <cmarrin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jan 8 19:23:40 2010 +0000
Implement full-screen video for Windows
https://bugs.webkit.org/show_bug.cgi?id=31318
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52998 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1619601..effa7fb 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2010-01-08 Chris Marrin <cmarrin at apple.com>
+
+ Reviewed by Adam Roben.
+
+ Implement full-screen video for Windows
+ https://bugs.webkit.org/show_bug.cgi?id=31318
+
+ This is mostly support logic for taking video
+ into and out of full-screen. It also contains the
+ QTMovieWin piece which adds support for the actual
+ full-screen window itself. Events from the window
+ are sent to the FullscreenVideosController for handling.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::addData):
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:
+ (WebCore::MediaPlayerPrivate::supportsFullscreen):
+ (WebCore::MediaPlayerPrivate::platformMedia):
+ * platform/graphics/win/QTMovieWin.cpp:
+ (QTMovieWinPrivate::QTMovieWinPrivate):
+ (QTMovieWin::initializeQuickTime):
+ (QTMovieWin::_handleMessages):
+ (QTMovieWin::enterFullscreen):
+ (QTMovieWin::exitFullscreen):
+ * platform/graphics/win/QTMovieWin.h:
+
2010-01-08 Matt Perry <mpcomplete at chromium.org>
Reviewed by Adam Barth.
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index a5beea1..7f20418 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -88,6 +88,18 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
{
}
+bool MediaPlayerPrivate::supportsFullscreen() const
+{
+ return true;
+}
+
+PlatformMedia MediaPlayerPrivate::platformMedia() const
+{
+ PlatformMedia p;
+ p.qtMovie = reinterpret_cast<QTMovie*>(m_qtMovie.get());
+ return p;
+}
+
class TaskTimer : TimerBase {
public:
static void initialize();
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index 2bccbbf..c035bf1 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -53,6 +53,9 @@ public:
private:
MediaPlayerPrivate(MediaPlayer*);
+ virtual bool supportsFullscreen() const;
+ virtual PlatformMedia platformMedia() const;
+
IntSize naturalSize() const;
bool hasVideo() const;
bool hasAudio() const;
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp
index 2d4c2ea..c7aad39 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWin.cpp
@@ -24,18 +24,15 @@
*/
#include "config.h"
-#include <windows.h>
-
#include "QTMovieWin.h"
// Put Movies.h first so build failures here point clearly to QuickTime
#include <Movies.h>
-#include <QuickTimeComponents.h>
-#include <GXMath.h>
-#include <QTML.h>
#include "QTMovieWinTimer.h"
-
+#include <GXMath.h>
+#include <QTML.h>
+#include <QuickTimeComponents.h>
#include <wtf/Assertions.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
@@ -50,6 +47,7 @@ static const long subTitleTrackType = 'sbtl';
static const long mpeg4ObjectDescriptionTrackType = 'odsm';
static const long mpeg4SceneDescriptionTrackType = 'sdsm';
static const long closedCaptionDisplayPropertyID = 'disp';
+static LPCTSTR fullscreenQTMovieWinPointerProp = TEXT("fullscreenQTMovieWinPointer");
// Resizing GWorlds is slow, give them a minimum size so size of small
// videos can be animated smoothly
@@ -130,6 +128,11 @@ public:
#if !ASSERT_DISABLED
bool m_scaleCached;
#endif
+ WindowPtr m_fullscreenWindow;
+ GWorldPtr m_fullscreenOrigGWorld;
+ Rect m_fullscreenRect;
+ QTMovieWinFullscreenClient* m_fullscreenClient;
+ char* m_fullscreenRestoreState;
};
QTMovieWinPrivate::QTMovieWinPrivate()
@@ -159,11 +162,19 @@ QTMovieWinPrivate::QTMovieWinPrivate()
#if !ASSERT_DISABLED
, m_scaleCached(false)
#endif
+ , m_fullscreenWindow(0)
+ , m_fullscreenOrigGWorld(0)
+ , m_fullscreenClient(0)
+ , m_fullscreenRestoreState(0)
{
+ Rect rect = { 0, 0, 0, 0 };
+ m_fullscreenRect = rect;
}
QTMovieWinPrivate::~QTMovieWinPrivate()
{
+ ASSERT(!m_fullscreenWindow);
+
endTask();
if (m_gWorld)
deleteGWorld();
@@ -359,7 +370,7 @@ void QTMovieWinPrivate::createGWorld()
bounds.left = 0;
bounds.right = m_gWorldWidth;
bounds.bottom = m_gWorldHeight;
- OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, NULL, NULL, NULL);
+ OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, 0, 0, 0);
if (err)
return;
GetMovieGWorld(m_movie, &m_savedGWorld, 0);
@@ -729,7 +740,7 @@ void QTMovieWin::load(CFURLRef url, bool preservesPitch)
moviePropCount++;
ASSERT(moviePropCount <= sizeof(movieProps)/sizeof(movieProps[0]));
- m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, NULL, &m_private->m_movie);
+ m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie);
end:
m_private->startTask();
@@ -953,7 +964,7 @@ static void initializeSupportedTypes()
continue;
if (!(infoCD.componentFlags & hasMovieImportMIMEList))
continue;
- QTAtomContainer mimeList = NULL;
+ QTAtomContainer mimeList = 0;
err = MovieImportGetMIMETypeList((ComponentInstance)comp, &mimeList);
if (err || !mimeList)
continue;
@@ -962,7 +973,7 @@ static void initializeSupportedTypes()
QTLockContainer(mimeList);
int typeCount = QTCountChildrenOfType(mimeList, kParentAtomIsContainer, kMimeInfoMimeTypeTag);
for (int typeIndex = 1; typeIndex <= typeCount; typeIndex++) {
- QTAtom mimeTag = QTFindChildByIndex(mimeList, 0, kMimeInfoMimeTypeTag, typeIndex, NULL);
+ QTAtom mimeTag = QTFindChildByIndex(mimeList, 0, kMimeInfoMimeTypeTag, typeIndex, 0);
if (!mimeTag)
continue;
char* atomData;
@@ -980,7 +991,7 @@ static void initializeSupportedTypes()
if (strncmp(typeBuffer, "audio/", 6) && strncmp(typeBuffer, "video/", 6))
continue;
- CFStringRef cfMimeType = CFStringCreateWithCString(NULL, typeBuffer, kCFStringEncodingUTF8);
+ CFStringRef cfMimeType = CFStringCreateWithCString(0, typeBuffer, kCFStringEncodingUTF8);
if (!cfMimeType)
continue;
@@ -1040,7 +1051,7 @@ bool QTMovieWin::initializeQuickTime()
if (!initialized) {
initialized = true;
// Initialize and check QuickTime version
- OSErr result = InitializeQTML(0);
+ OSErr result = InitializeQTML(kInitializeQTMLEnableDoubleBufferedSurface);
if (result == noErr)
result = Gestalt(gestaltQuickTime, &quickTimeVersion);
if (result != noErr) {
@@ -1058,15 +1069,80 @@ bool QTMovieWin::initializeQuickTime()
return initializationSucceeded;
}
+LRESULT QTMovieWin::fullscreenWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ QTMovieWin* movie = static_cast<QTMovieWin*>(GetProp(wnd, fullscreenQTMovieWinPointerProp));
+
+ if (message == WM_DESTROY)
+ RemoveProp(wnd, fullscreenQTMovieWinPointerProp);
+
+ if (!movie)
+ return DefWindowProc(wnd, message, wParam, lParam);
+
+ return movie->m_private->m_fullscreenClient->fullscreenClientWndProc(wnd, message, wParam, lParam);
+}
+
+HWND QTMovieWin::enterFullscreen(QTMovieWinFullscreenClient* client)
+{
+ m_private->m_fullscreenClient = client;
+
+ BeginFullScreen(&m_private->m_fullscreenRestoreState, 0, 0, 0, &m_private->m_fullscreenWindow, 0, fullScreenAllowEvents);
+ QTMLSetWindowWndProc(m_private->m_fullscreenWindow, fullscreenWndProc);
+ CreatePortAssociation(GetPortNativeWindow(m_private->m_fullscreenWindow), 0, 0);
+
+ GetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ GetMovieGWorld(m_private->m_movie, &m_private->m_fullscreenOrigGWorld, 0);
+ SetMovieGWorld(m_private->m_movie, reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow), GetGWorldDevice(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow)));
+
+ // Set the size of the box to preserve aspect ratio
+ Rect rect = m_private->m_fullscreenWindow->portRect;
+
+ float movieRatio = static_cast<float>(m_private->m_width) / m_private->m_height;
+ int windowWidth = rect.right - rect.left;
+ int windowHeight = rect.bottom - rect.top;
+ float windowRatio = static_cast<float>(windowWidth) / windowHeight;
+ int actualWidth = (windowRatio > movieRatio) ? (windowHeight * movieRatio) : windowWidth;
+ int actualHeight = (windowRatio < movieRatio) ? (windowWidth / movieRatio) : windowHeight;
+ int offsetX = (windowWidth - actualWidth) / 2;
+ int offsetY = (windowHeight - actualHeight) / 2;
+
+ rect.left = offsetX;
+ rect.right = offsetX + actualWidth;
+ rect.top = offsetY;
+ rect.bottom = offsetY + actualHeight;
+
+ SetMovieBox(m_private->m_movie, &rect);
+ ShowHideTaskBar(true);
+
+ // Set the 'this' pointer on the HWND
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ SetProp(wnd, fullscreenQTMovieWinPointerProp, static_cast<HANDLE>(this));
+
+ return wnd;
+}
+
+void QTMovieWin::exitFullscreen()
+{
+ if (!m_private->m_fullscreenWindow)
+ return;
+
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ DestroyPortAssociation(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow));
+ SetMovieGWorld(m_private->m_movie, m_private->m_fullscreenOrigGWorld, 0);
+ EndFullScreen(m_private->m_fullscreenRestoreState, 0L);
+ SetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ m_private->m_fullscreenWindow = 0;
+}
+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- return TRUE;
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- return FALSE;
+ case DLL_PROCESS_ATTACH:
+ return TRUE;
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ return FALSE;
}
ASSERT_NOT_REACHED();
return FALSE;
diff --git a/WebCore/platform/graphics/win/QTMovieWin.h b/WebCore/platform/graphics/win/QTMovieWin.h
index 778f9aa..796b756 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.h
+++ b/WebCore/platform/graphics/win/QTMovieWin.h
@@ -27,6 +27,7 @@
#define QTMovieWin_h
#include <Unicode.h>
+#include <windows.h>
#ifdef QTMOVIEWIN_EXPORTS
#define QTMOVIEWIN_API __declspec(dllexport)
@@ -45,6 +46,11 @@ public:
virtual void movieNewImageAvailable(QTMovieWin*) = 0;
};
+class QTMovieWinFullscreenClient {
+public:
+ virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM) = 0;
+};
+
enum {
QTMovieLoadStateError = -1L,
QTMovieLoadStateLoaded = 2000L,
@@ -104,8 +110,13 @@ public:
static unsigned countSupportedTypes();
static void getSupportedType(unsigned index, const UChar*& str, unsigned& len);
+ // Returns the full-screen window created
+ HWND enterFullscreen(QTMovieWinFullscreenClient*);
+ void exitFullscreen();
+
private:
void load(CFURLRef, bool preservesPitch);
+ static LRESULT fullscreenWndProc(HWND, UINT message, WPARAM, LPARAM);
QTMovieWinPrivate* m_private;
bool m_disabled;
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index 283a8a0..78b924f 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,45 @@
+2010-01-08 Chris Marrin <cmarrin at apple.com>
+
+ Reviewed by Adam Roben.
+
+ Implement full-screen video for Windows
+ https://bugs.webkit.org/show_bug.cgi?id=31318
+
+ This adds a full-screen controller, FullscreenVideoController,
+ which manages going in and out of full-screen. The actual
+ full-screen window is created and managed by logic added
+ to QTMovieWin. FullscreenVideoController also creates and
+ manages a HUD. The HUD renders and manages events to
+ control the playing video. Movie controller events go to
+ FullscreenVideoController which then sends them to HTMLMediaElement,
+ which is passed to the controller by WebView, which gets the call
+ to go into full-screen mode from HTMLMediaElement via
+ ChromeClient.
+
+ I've also updated the icons so the related sets (Play/Pause and
+ volume high/volume low/exit fullscreen) are the same size. This
+ allows me to position them using common code.
+
+ * WebCoreSupport/WebChromeClient.cpp:
+ (WebChromeClient::supportsFullscreenForNode):
+ (WebChromeClient::enterFullscreenForNode):
+ (WebChromeClient::exitFullscreenForNode):
+ * WebCoreSupport/WebChromeClient.h:
+ * WebKit.vcproj/WebKit.vcproj:
+ * WebKit.vcproj/fsVideoAudioVolumeHigh.png:
+ * WebKit.vcproj/fsVideoAudioVolumeLow.png:
+ * WebKit.vcproj/fsVideoExitFullscreen.png:
+ * WebKit.vcproj/fsVideoPause.png:
+ * WebKit.vcproj/fsVideoPlay.png:
+ * WebKitDLL.cpp:
+ (loadResourceIntoBuffer):
+ * FullscreenVideoController.cpp: Added.
+ * FullscreenVideoController.h: Added.
+ * WebView.cpp:
+ (WebView::enterFullscreenForNode):
+ (WebView::exitFullscreen):
+ * WebView.h:
+
2010-01-08 Brent Fulgham <bfulgham at webkit.org>
Unreviewed correction.
diff --git a/WebKit/win/FullscreenVideoController.cpp b/WebKit/win/FullscreenVideoController.cpp
new file mode 100644
index 0000000..6b8e5ac
--- /dev/null
+++ b/WebKit/win/FullscreenVideoController.cpp
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+
+#include "FullscreenVideoController.h"
+
+#include "WebKitDLL.h"
+#include <ApplicationServices/ApplicationServices.h>
+#include <WebCore/BitmapInfo.h>
+#include <WebCore/Font.h>
+#include <WebCore/FontSelector.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/TextRun.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#include <windowsx.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace std;
+using namespace WebCore;
+
+static const float timerInterval = 0.033;
+
+// HUD Size
+static const int windowHeight = 59;
+static const int windowWidth = 438;
+
+// Margins and button sizes
+static const int margin = 9;
+static const int marginTop = 9;
+static const int buttonSize = 25;
+static const int buttonMiniSize = 16;
+static const int volumeSliderWidth = 50;
+static const int timeSliderWidth = 310;
+static const int sliderHeight = 8;
+static const int volumeSliderButtonSize = 10;
+static const int timeSliderButtonSize = 8;
+static const int textSize = 11;
+static const float initialHUDPositionY = 0.9; // Initial Y position of HUD in percentage from top of screen
+
+// Background values
+static const int borderRadius = 12;
+static const int borderThickness = 2;
+
+// Colors
+static const unsigned int backgroundColor = 0xA0202020;
+static const unsigned int borderColor = 0xFFA0A0A0;
+static const unsigned int sliderGutterColor = 0xFF141414;
+static const unsigned int sliderButtonColor = 0xFF808080;
+static const unsigned int textColor = 0xFFFFFFFF;
+
+HUDButton::HUDButton(HUDButtonType type, const IntPoint& position)
+ : HUDWidget(IntRect(position, IntSize()))
+ , m_type(type)
+ , m_showAltButton(false)
+{
+ const char* buttonResource = 0;
+ const char* buttonResourceAlt = 0;
+ switch (m_type) {
+ case PlayPauseButton:
+ buttonResource = "fsVideoPlay";
+ buttonResourceAlt = "fsVideoPause";
+ break;
+ case TimeSliderButton:
+ break;
+ case VolumeUpButton:
+ buttonResource = "fsVideoAudioVolumeHigh";
+ break;
+ case VolumeSliderButton:
+ break;
+ case VolumeDownButton:
+ buttonResource = "fsVideoAudioVolumeLow";
+ break;
+ case ExitFullscreenButton:
+ buttonResource = "fsVideoExitFullscreen";
+ break;
+ }
+
+ if (buttonResource) {
+ m_buttonImage = Image::loadPlatformResource(buttonResource);
+ m_rect.setWidth(m_buttonImage->width());
+ m_rect.setHeight(m_buttonImage->height());
+ }
+ if (buttonResourceAlt)
+ m_buttonImageAlt = Image::loadPlatformResource(buttonResourceAlt);
+}
+
+void HUDButton::draw(GraphicsContext& context)
+{
+ Image* image = (m_showAltButton && m_buttonImageAlt) ? m_buttonImageAlt.get() : m_buttonImage.get();
+ context.drawImage(image, DeviceColorSpace, m_rect.location());
+}
+
+HUDSlider::HUDSlider(HUDSliderButtonShape shape, int buttonSize, const IntRect& rect)
+ : HUDWidget(rect)
+ , m_buttonShape(shape)
+ , m_buttonSize(buttonSize)
+ , m_buttonPosition(0)
+ , m_dragStartOffset(0)
+{
+}
+
+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);
+
+ // Draw button
+ context.setStrokeColor(Color(sliderButtonColor), DeviceColorSpace);
+ context.setFillColor(Color(sliderButtonColor), DeviceColorSpace);
+
+ 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));
+ return;
+ }
+
+ // Draw a diamond
+ FloatPoint points[4];
+ float half = static_cast<float>(m_buttonSize) / 2;
+ points[0].setX(m_rect.location().x() + m_buttonPosition + half);
+ points[0].setY(m_rect.location().y());
+ points[1].setX(m_rect.location().x() + m_buttonPosition + m_buttonSize);
+ points[1].setY(m_rect.location().y() + half);
+ points[2].setX(m_rect.location().x() + m_buttonPosition + half);
+ points[2].setY(m_rect.location().y() + m_buttonSize);
+ points[3].setX(m_rect.location().x() + m_buttonPosition);
+ points[3].setY(m_rect.location().y() + half);
+ context.drawConvexPolygon(4, points, true);
+}
+
+void HUDSlider::drag(const IntPoint& point, bool start)
+{
+ if (start) {
+ // When we start, we need to snap the slider position to the x position if we clicked the gutter.
+ // But if we click the button, we need to drag relative to where we clicked down. We only need
+ // to check X because we would not even get here unless Y were already inside.
+ int relativeX = point.x() - m_rect.location().x();
+ if (relativeX >= m_buttonPosition && relativeX <= m_buttonPosition + m_buttonSize)
+ m_dragStartOffset = point.x() - m_buttonPosition;
+ else
+ m_dragStartOffset = m_rect.location().x() + m_buttonSize / 2;
+ }
+
+ m_buttonPosition = max(0, min(m_rect.width() - m_buttonSize, point.x() - m_dragStartOffset));
+}
+
+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))
+ , m_volumeSliderButton(HUDButton::VolumeSliderButton, IntPoint(0, 0))
+ , m_volumeDownButton(HUDButton::VolumeDownButton, IntPoint(margin, marginTop + (buttonSize - buttonMiniSize) / 2))
+ , m_exitFullscreenButton(HUDButton::ExitFullscreenButton, IntPoint(windowWidth - 2 * margin - buttonMiniSize, marginTop + (buttonSize - buttonMiniSize) / 2))
+ , m_volumeSlider(HUDSlider::RoundButton, volumeSliderButtonSize, IntRect(IntPoint(margin + buttonMiniSize, marginTop + (buttonSize - buttonMiniSize) / 2 + buttonMiniSize / 2 - sliderHeight / 2), IntSize(volumeSliderWidth, sliderHeight)))
+ , m_timeSlider(HUDSlider::DiamondButton, timeSliderButtonSize, IntRect(IntPoint(windowWidth / 2 - timeSliderWidth / 2, windowHeight - margin - sliderHeight), IntSize(timeSliderWidth, sliderHeight)))
+ , m_hitWidget(0)
+ , m_movingWindow(false)
+ , m_timer(this, &FullscreenVideoController::timerFired)
+{
+}
+
+FullscreenVideoController::~FullscreenVideoController()
+{
+ if (movie())
+ movie()->exitFullscreen();
+}
+
+QTMovieWin* FullscreenVideoController::movie() const
+{
+ return m_mediaElement ? reinterpret_cast<QTMovieWin*>(m_mediaElement->platformMedia().qtMovie) : 0;
+}
+
+void FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement)
+{
+ if (mediaElement == m_mediaElement)
+ return;
+
+ m_mediaElement = mediaElement;
+ if (!m_mediaElement) {
+ // Can't do full-screen, just get out
+ exitFullscreen();
+ }
+}
+
+void FullscreenVideoController::enterFullscreen()
+{
+ if (!movie())
+ return;
+
+ m_videoWindow = movie()->enterFullscreen(this);
+
+ RECT windowRect;
+ GetClientRect(m_videoWindow, &windowRect);
+ m_fullscreenSize.setWidth(windowRect.right - windowRect.left);
+ m_fullscreenSize.setHeight(windowRect.bottom - windowRect.top);
+
+ createHUDWindow();
+}
+
+void FullscreenVideoController::exitFullscreen()
+{
+ if (movie())
+ movie()->exitFullscreen();
+
+ m_videoWindow = 0;
+ SetWindowLongPtr(m_hudWindow, 0, 0);
+ DestroyWindow(m_hudWindow);
+ m_hudWindow = 0;
+}
+
+bool FullscreenVideoController::canPlay() const
+{
+ return m_mediaElement && m_mediaElement->canPlay();
+}
+
+void FullscreenVideoController::play()
+{
+ if (m_mediaElement)
+ m_mediaElement->play();
+}
+
+void FullscreenVideoController::pause()
+{
+ if (m_mediaElement)
+ m_mediaElement->pause();
+}
+
+float FullscreenVideoController::volume() const
+{
+ return m_mediaElement ? m_mediaElement->volume() : 0;
+}
+
+void FullscreenVideoController::setVolume(float volume)
+{
+ if (m_mediaElement) {
+ ExceptionCode ec;
+ m_mediaElement->setVolume(volume, ec);
+ }
+}
+
+float FullscreenVideoController::currentTime() const
+{
+ return m_mediaElement ? m_mediaElement->currentTime() : 0;
+}
+
+void FullscreenVideoController::setCurrentTime(float value)
+{
+ if (m_mediaElement) {
+ ExceptionCode ec;
+ m_mediaElement->setCurrentTime(value, ec);
+ }
+}
+
+float FullscreenVideoController::duration() const
+{
+ return m_mediaElement ? m_mediaElement->duration() : 0;
+}
+
+void FullscreenVideoController::beginScrubbing()
+{
+ if (m_mediaElement)
+ m_mediaElement->beginScrubbing();
+}
+
+void FullscreenVideoController::endScrubbing()
+{
+ if (m_mediaElement)
+ m_mediaElement->endScrubbing();
+}
+
+LRESULT FullscreenVideoController::fullscreenClientWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WM_CHAR:
+ onChar(wParam);
+ break;
+ case WM_LBUTTONDOWN:
+ onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ case WM_MOUSEMOVE:
+ onMouseMove(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ case WM_LBUTTONUP:
+ onMouseUp(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ }
+
+ return DefWindowProc(wnd, message, wParam, lParam);
+}
+
+static const LPCWSTR fullscreenVideeoHUDWindowClassName = L"fullscreenVideeoHUDWindowClass";
+
+void FullscreenVideoController::registerHUDWindowClass()
+{
+ static bool haveRegisteredHUDWindowClass;
+ if (haveRegisteredHUDWindowClass)
+ return;
+
+ haveRegisteredHUDWindowClass = true;
+
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = hudWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 4;
+ wcex.hInstance = gInstance;
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = fullscreenVideeoHUDWindowClassName;
+ wcex.hIconSm = 0;
+
+ RegisterClassEx(&wcex);
+}
+
+void FullscreenVideoController::createHUDWindow()
+{
+ m_hudPosition.setX((m_fullscreenSize.width() - windowWidth) / 2);
+ m_hudPosition.setY(m_fullscreenSize.height() * initialHUDPositionY - windowHeight / 2);
+
+ // Local variable that will hold the returned pixels. No need to cleanup this value. It
+ // will get cleaned up when m_bitmap is destroyed in the dtor
+ void* pixels;
+ BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(IntSize(windowWidth, windowHeight));
+ m_bitmap.set(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0));
+
+ // 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);
+
+ m_playPauseButton.setShowAltButton(!canPlay());
+ m_volumeSlider.setValue(volume());
+ m_timeSlider.setValue(currentTime() / duration());
+
+ if (!canPlay())
+ m_timer.startRepeating(timerInterval);
+
+ registerHUDWindowClass();
+
+ m_hudWindow = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
+ fullscreenVideeoHUDWindowClassName, 0, WS_POPUP | WS_VISIBLE,
+ m_hudPosition.x(), m_hudPosition.y(), 0, 0, 0, 0, gInstance, 0);
+ ASSERT(::IsWindow(m_hudWindow));
+ SetWindowLongPtr(m_hudWindow, 0, reinterpret_cast<LONG_PTR>(this));
+
+ draw();
+}
+
+static String timeToString(float time)
+{
+ if (!isfinite(time))
+ time = 0;
+ int seconds = fabsf(time);
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+
+ if (hours) {
+ if (hours > 9)
+ return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+ return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+ }
+
+ return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
+}
+
+void FullscreenVideoController::draw()
+{
+ HDC windowDC = GetDC(m_hudWindow);
+ HDC bitmapDC = CreateCompatibleDC(windowDC);
+ ::ReleaseDC(m_hudWindow, windowDC);
+ SelectObject(bitmapDC, m_bitmap.get());
+
+ GraphicsContext context(bitmapDC, true);
+
+ context.save();
+
+ // Draw the background
+ IntSize outerRadius(borderRadius, borderRadius);
+ IntRect outerRect(0, 0, windowWidth, windowHeight);
+ 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.setCompositeOperation(CompositeCopy);
+ context.fillRoundedRect(innerRect, innerRadius, innerRadius, innerRadius, innerRadius, Color(backgroundColor), DeviceColorSpace);
+
+ // Draw the widgets
+ m_playPauseButton.draw(context);
+ m_volumeUpButton.draw(context);
+ m_volumeSliderButton.draw(context);
+ m_volumeDownButton.draw(context);
+ m_timeSliderButton.draw(context);
+ m_exitFullscreenButton.draw(context);
+ m_volumeSlider.draw(context);
+ m_timeSlider.draw(context);
+
+ // Draw the text strings
+ FontDescription desc;
+
+ NONCLIENTMETRICS metrics;
+ metrics.cbSize = sizeof(metrics);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
+ FontFamily family;
+ family.setFamily(metrics.lfSmCaptionFont.lfFaceName);
+ desc.setFamily(family);
+
+ desc.setComputedSize(textSize);
+ Font font = Font(desc, 0, 0);
+ font.update(0);
+
+ String s;
+
+ // The y positioning of these two text strings is tricky because they are so small. They
+ // are currently positioned relative to the center of the slider and then down the font
+ // height / 4 (which is actually half of font height /2), which positions the center of
+ // the text at the center of the slider.
+ // Left string
+ s = timeToString(currentTime());
+ TextRun leftText(s);
+ context.setFillColor(Color(textColor), DeviceColorSpace);
+ 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.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + font.height() / 4));
+
+ // Copy to the window
+ BLENDFUNCTION blendFunction = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
+ SIZE size = { windowWidth, windowHeight };
+ POINT sourcePoint = {0, 0};
+ POINT destPoint = { m_hudPosition.x(), m_hudPosition.y() };
+ BOOL result = UpdateLayeredWindow(m_hudWindow, 0, &destPoint, &size, bitmapDC, &sourcePoint, 0, &blendFunction, ULW_ALPHA);
+
+ context.restore();
+
+ ::DeleteDC(bitmapDC);
+}
+
+LRESULT FullscreenVideoController::hudWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LONG_PTR longPtr = GetWindowLongPtr(wnd, 0);
+ FullscreenVideoController* controller = reinterpret_cast<FullscreenVideoController*>(longPtr);
+ if (!controller)
+ return DefWindowProc(wnd, message, wParam, lParam);
+
+ switch (message) {
+ case WM_CHAR:
+ controller->onChar(wParam);
+ break;
+ case WM_LBUTTONDOWN:
+ controller->onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ case WM_MOUSEMOVE:
+ controller->onMouseMove(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ case WM_LBUTTONUP:
+ controller->onMouseUp(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ break;
+ }
+
+ return DefWindowProc(wnd, message, wParam, lParam);
+}
+
+void FullscreenVideoController::onChar(int c)
+{
+ if (c == VK_ESCAPE) {
+ if (m_mediaElement)
+ m_mediaElement->exitFullscreen();
+ } else if (c == VK_SPACE)
+ togglePlay();
+}
+
+void FullscreenVideoController::timerFired(Timer<FullscreenVideoController>*)
+{
+ // Update the time slider
+ m_timeSlider.setValue(currentTime() / duration());
+ draw();
+}
+
+void FullscreenVideoController::onMouseDown(const IntPoint& 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)
+ return;
+
+ m_hitWidget = 0;
+ m_movingWindow = false;
+
+ if (m_playPauseButton.hitTest(convertedPoint))
+ m_hitWidget = &m_playPauseButton;
+ else if (m_exitFullscreenButton.hitTest(convertedPoint))
+ m_hitWidget = &m_exitFullscreenButton;
+ else if (m_volumeUpButton.hitTest(convertedPoint))
+ m_hitWidget = &m_volumeUpButton;
+ else if (m_volumeDownButton.hitTest(convertedPoint))
+ m_hitWidget = &m_volumeDownButton;
+ else if (m_volumeSlider.hitTest(convertedPoint)) {
+ m_hitWidget = &m_volumeSlider;
+ m_volumeSlider.drag(convertedPoint, true);
+ setVolume(m_volumeSlider.value());
+ } else if (m_timeSlider.hitTest(convertedPoint)) {
+ m_hitWidget = &m_timeSlider;
+ m_timeSlider.drag(convertedPoint, true);
+ beginScrubbing();
+ setCurrentTime(m_timeSlider.value() * duration());
+ }
+
+ // If we did not pick any of our widgets we are starting a window move
+ if (!m_hitWidget) {
+ m_moveOffset = convertedPoint;
+ m_movingWindow = true;
+ }
+
+ draw();
+}
+
+void FullscreenVideoController::onMouseMove(const IntPoint& point)
+{
+ IntPoint convertedPoint(fullScreenToHUDCoordinates(point));
+
+ if (m_hitWidget) {
+ m_hitWidget->drag(convertedPoint, false);
+ if (m_hitWidget == &m_volumeSlider)
+ setVolume(m_volumeSlider.value());
+ else if (m_hitWidget == &m_timeSlider)
+ setCurrentTime(m_timeSlider.value() * duration());
+ draw();
+ } else if (m_movingWindow)
+ m_hudPosition.move(convertedPoint.x() - m_moveOffset.x(), convertedPoint.y() - m_moveOffset.y());
+}
+
+void FullscreenVideoController::onMouseUp(const IntPoint& point)
+{
+ IntPoint convertedPoint(fullScreenToHUDCoordinates(point));
+ m_movingWindow = false;
+
+ if (m_hitWidget) {
+ if (m_hitWidget == &m_playPauseButton && m_playPauseButton.hitTest(convertedPoint))
+ togglePlay();
+ else if (m_hitWidget == &m_volumeUpButton && m_volumeUpButton.hitTest(convertedPoint)) {
+ setVolume(1);
+ m_volumeSlider.setValue(1);
+ } else if (m_hitWidget == &m_volumeDownButton && m_volumeDownButton.hitTest(convertedPoint)) {
+ setVolume(0);
+ m_volumeSlider.setValue(0);
+ } else if (m_hitWidget == &m_timeSlider)
+ endScrubbing();
+ else if (m_hitWidget == &m_exitFullscreenButton && m_exitFullscreenButton.hitTest(convertedPoint)) {
+ m_hitWidget = 0;
+ if (m_mediaElement)
+ m_mediaElement->exitFullscreen();
+ return;
+ }
+ }
+
+ m_hitWidget = 0;
+ draw();
+}
+
+void FullscreenVideoController::togglePlay()
+{
+ if (canPlay())
+ play();
+ else
+ pause();
+
+ m_playPauseButton.setShowAltButton(!canPlay());
+
+ // Run a timer while the video is playing so we can keep the time
+ // slider and time values up to date.
+ if (!canPlay())
+ m_timer.startRepeating(timerInterval);
+ else
+ m_timer.stop();
+
+ draw();
+}
+
+#endif
diff --git a/WebKit/win/FullscreenVideoController.h b/WebKit/win/FullscreenVideoController.h
new file mode 100644
index 0000000..b39e30c
--- /dev/null
+++ b/WebKit/win/FullscreenVideoController.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FullscreenVideoController_h
+#define FullscreenVideoController_h
+
+#if ENABLE(VIDEO)
+
+#include "QTMovieWin.h"
+
+#include <WebCore/HTMLMediaElement.h>
+#include <WebCore/Image.h>
+#include <WebCore/IntPoint.h>
+#include <WebCore/IntSize.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class GraphicsContext;
+}
+
+class HUDWidget {
+public:
+ HUDWidget(const WebCore::IntRect& rect) : m_rect(rect) { }
+
+ virtual ~HUDWidget() { }
+
+ virtual void draw(WebCore::GraphicsContext&) = 0;
+ virtual void drag(const WebCore::IntPoint&, bool start) = 0;
+ bool hitTest(const WebCore::IntPoint& point) const { return m_rect.contains(point); }
+
+protected:
+ WebCore::IntRect m_rect;
+};
+
+class HUDButton : public HUDWidget {
+public:
+ enum HUDButtonType {
+ NoButton,
+ PlayPauseButton,
+ TimeSliderButton,
+ VolumeUpButton,
+ VolumeSliderButton,
+ VolumeDownButton,
+ ExitFullscreenButton
+ };
+
+ HUDButton(HUDButtonType, const WebCore::IntPoint&);
+ ~HUDButton() { }
+
+ virtual void draw(WebCore::GraphicsContext&);
+ virtual void drag(const WebCore::IntPoint&, bool start) { }
+ void setShowAltButton(bool b) { m_showAltButton = b; }
+
+private:
+ RefPtr<WebCore::Image> m_buttonImage;
+ RefPtr<WebCore::Image> m_buttonImageAlt;
+ HUDButtonType m_type;
+ bool m_showAltButton;
+};
+
+class HUDSlider : public HUDWidget {
+public:
+ enum HUDSliderButtonShape { RoundButton, DiamondButton };
+
+ HUDSlider(HUDSliderButtonShape, int buttonSize, const WebCore::IntRect& rect);
+ ~HUDSlider() { }
+
+ virtual void draw(WebCore::GraphicsContext&);
+ virtual void drag(const WebCore::IntPoint&, bool start);
+ float value() const { return static_cast<float>(m_buttonPosition) / (m_rect.width() - m_buttonSize); }
+ void setValue(float value) { m_buttonPosition = static_cast<int>(value * (m_rect.width() - m_buttonSize)); }
+
+private:
+ HUDSliderButtonShape m_buttonShape;
+ int m_buttonSize;
+ int m_buttonPosition;
+ int m_dragStartOffset;
+};
+
+class FullscreenVideoController : QTMovieWinFullscreenClient, public Noncopyable {
+public:
+ FullscreenVideoController();
+ virtual ~FullscreenVideoController();
+
+ void setMediaElement(WebCore::HTMLMediaElement*);
+ WebCore::HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); }
+
+ void enterFullscreen();
+ void exitFullscreen();
+
+private:
+ // QTMovieWinFullscreenClient
+ virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM);
+
+ void ensureWindow();
+ QTMovieWin* movie() const;
+
+ bool canPlay() const;
+ void play();
+ void pause();
+ float volume() const;
+ void setVolume(float);
+ float currentTime() const;
+ void setCurrentTime(float);
+ float duration() const;
+ void beginScrubbing();
+ void endScrubbing();
+
+ WebCore::IntPoint fullScreenToHUDCoordinates(const WebCore::IntPoint& point) const
+ {
+ return WebCore::IntPoint(point.x()- m_hudPosition.x(), point.y() - m_hudPosition.y());
+ }
+
+ static void registerHUDWindowClass();
+ static LRESULT CALLBACK hudWndProc(HWND, UINT message, WPARAM, LPARAM);
+ void createHUDWindow();
+ void timerFired(WebCore::Timer<FullscreenVideoController>*);
+
+ void togglePlay();
+ void draw();
+
+ void onChar(int c);
+ void onMouseDown(const WebCore::IntPoint&);
+ void onMouseMove(const WebCore::IntPoint&);
+ void onMouseUp(const WebCore::IntPoint&);
+
+ RefPtr<WebCore::HTMLMediaElement> m_mediaElement;
+
+ HWND m_hudWindow, m_videoWindow;
+ OwnPtr<HBITMAP> m_bitmap;
+ WebCore::IntSize m_fullscreenSize;
+ WebCore::IntPoint m_hudPosition;
+
+ HUDButton m_playPauseButton;
+ HUDButton m_timeSliderButton;
+ HUDButton m_volumeUpButton;
+ HUDButton m_volumeSliderButton;
+ HUDButton m_volumeDownButton;
+ HUDButton m_exitFullscreenButton;
+ HUDSlider m_volumeSlider;
+ HUDSlider m_timeSlider;
+
+ HUDWidget* m_hitWidget;
+ WebCore::IntPoint m_moveOffset;
+ bool m_movingWindow;
+ WebCore::Timer<FullscreenVideoController> m_timer;
+};
+
+#endif
+
+#endif // FullscreenVideoController_h
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
index 6e82caf..002a629 100644
--- a/WebKit/win/WebCoreSupport/WebChromeClient.cpp
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
@@ -44,6 +44,7 @@
#include <WebCore/FloatRect.h>
#include <WebCore/FrameLoadRequest.h>
#include <WebCore/FrameView.h>
+#include <WebCore/HTMLNames.h>
#include <WebCore/LocalizedStrings.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
@@ -773,3 +774,23 @@ COMPtr<IWebUIDelegate> WebChromeClient::uiDelegate()
m_webView->uiDelegate(&delegate);
return delegate;
}
+
+#if ENABLE(VIDEO)
+
+bool WebChromeClient::supportsFullscreenForNode(const Node* node)
+{
+ return node->hasTagName(HTMLNames::videoTag);
+}
+
+void WebChromeClient::enterFullscreenForNode(Node* node)
+{
+ m_webView->enterFullscreenForNode(node);
+}
+
+void WebChromeClient::exitFullscreenForNode(Node*)
+{
+ m_webView->exitFullscreen();
+}
+
+#endif
+
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.h b/WebKit/win/WebCoreSupport/WebChromeClient.h
index e0c59ae..5198e7c 100644
--- a/WebKit/win/WebCoreSupport/WebChromeClient.h
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.h
@@ -147,6 +147,12 @@ public:
virtual void requestGeolocationPermissionForFrame(WebCore::Frame*, WebCore::Geolocation*);
+#if ENABLE(VIDEO)
+ virtual bool supportsFullscreenForNode(const WebCore::Node*);
+ virtual void enterFullscreenForNode(WebCore::Node*);
+ virtual void exitFullscreenForNode(WebCore::Node*);
+#endif
+
#if ENABLE(NOTIFICATIONS)
virtual WebCore::NotificationPresenter* notificationPresenter() const { return reinterpret_cast<WebCore::NotificationPresenter*>(m_notificationsDelegate.get()); }
#endif
diff --git a/WebKit/win/WebKit.vcproj/WebKit.vcproj b/WebKit/win/WebKit.vcproj/WebKit.vcproj
index 8259a6a..eee7b8a 100644
--- a/WebKit/win/WebKit.vcproj/WebKit.vcproj
+++ b/WebKit/win/WebKit.vcproj/WebKit.vcproj
@@ -582,6 +582,10 @@
>
</File>
<File
+ RelativePath="..\FullscreenVideoController.h"
+ >
+ </File>
+ <File
RelativePath="..\MarshallingHelpers.h"
>
</File>
@@ -894,6 +898,10 @@
>
</File>
<File
+ RelativePath="..\FullscreenVideoController.cpp"
+ >
+ </File>
+ <File
RelativePath="..\MemoryStream.cpp"
>
</File>
diff --git a/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeHigh.png b/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeHigh.png
index 713669e..d04df37 100755
Binary files a/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeHigh.png and b/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeHigh.png differ
diff --git a/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeLow.png b/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeLow.png
index 3b0c70e..e824a21 100755
Binary files a/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeLow.png and b/WebKit/win/WebKit.vcproj/fsVideoAudioVolumeLow.png differ
diff --git a/WebKit/win/WebKit.vcproj/fsVideoExitFullscreen.png b/WebKit/win/WebKit.vcproj/fsVideoExitFullscreen.png
index b6e0df6..01ce692 100755
Binary files a/WebKit/win/WebKit.vcproj/fsVideoExitFullscreen.png and b/WebKit/win/WebKit.vcproj/fsVideoExitFullscreen.png differ
diff --git a/WebKit/win/WebKit.vcproj/fsVideoPause.png b/WebKit/win/WebKit.vcproj/fsVideoPause.png
index 004520d..b98fb36 100755
Binary files a/WebKit/win/WebKit.vcproj/fsVideoPause.png and b/WebKit/win/WebKit.vcproj/fsVideoPause.png differ
diff --git a/WebKit/win/WebKit.vcproj/fsVideoPlay.png b/WebKit/win/WebKit.vcproj/fsVideoPlay.png
index fb44f87..035aeb2 100755
Binary files a/WebKit/win/WebKit.vcproj/fsVideoPlay.png and b/WebKit/win/WebKit.vcproj/fsVideoPlay.png differ
diff --git a/WebKit/win/WebKitDLL.cpp b/WebKit/win/WebKitDLL.cpp
index c34fe4b..9f4eaeb 100644
--- a/WebKit/win/WebKitDLL.cpp
+++ b/WebKit/win/WebKitDLL.cpp
@@ -179,6 +179,16 @@ PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char* name)
idr = IDR_ZOOM_OUT_CURSOR;
else if (!strcmp(name, "verticalTextCursor"))
idr = IDR_VERTICAL_TEXT_CURSOR;
+ else if (!strcmp(name, "fsVideoAudioVolumeHigh"))
+ idr = IDR_FS_VIDEO_AUDIO_VOLUME_HIGH;
+ else if (!strcmp(name, "fsVideoAudioVolumeLow"))
+ idr = IDR_FS_VIDEO_AUDIO_VOLUME_LOW;
+ else if (!strcmp(name, "fsVideoExitFullscreen"))
+ idr = IDR_FS_VIDEO_EXIT_FULLSCREEN;
+ else if (!strcmp(name, "fsVideoPause"))
+ idr = IDR_FS_VIDEO_PAUSE;
+ else if (!strcmp(name, "fsVideoPlay"))
+ idr = IDR_FS_VIDEO_PLAY;
else
return 0;
diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp
index da6772a..3f28c5b 100644
--- a/WebKit/win/WebView.cpp
+++ b/WebKit/win/WebView.cpp
@@ -24,11 +24,12 @@
*/
#include "config.h"
-#include "WebKitDLL.h"
+
#include "WebView.h"
#include "CFDictionaryPropertyBag.h"
#include "DOMCoreClasses.h"
+#include "FullscreenVideoController.h"
#include "MarshallingHelpers.h"
#include "SoftLinking.h"
#include "WebBackForwardList.h"
@@ -46,6 +47,7 @@
#include "WebInspector.h"
#include "WebInspectorClient.h"
#include "WebKit.h"
+#include "WebKitDLL.h"
#include "WebKitLogging.h"
#include "WebKitStatisticsPrivate.h"
#include "WebKitSystemBits.h"
@@ -58,17 +60,17 @@
#include <JavaScriptCore/InitializeThreading.h>
#include <JavaScriptCore/JSLock.h>
#include <JavaScriptCore/JSValue.h>
-#include <WebCore/ApplicationCacheStorage.h>
#include <WebCore/AXObjectCache.h>
+#include <WebCore/ApplicationCacheStorage.h>
+#include <WebCore/BString.h>
#include <WebCore/BackForwardList.h>
#include <WebCore/BitmapInfo.h>
-#include <WebCore/BString.h>
+#include <WebCore/CString.h>
#include <WebCore/Cache.h>
#include <WebCore/Chrome.h>
#include <WebCore/ContextMenu.h>
#include <WebCore/ContextMenuController.h>
#include <WebCore/CookieStorageWin.h>
-#include <WebCore/CString.h>
#include <WebCore/Cursor.h>
#include <WebCore/Document.h>
#include <WebCore/DragController.h>
@@ -77,14 +79,16 @@
#include <WebCore/EventHandler.h>
#include <WebCore/EventNames.h>
#include <WebCore/FileSystem.h>
-#include <WebCore/FocusController.h>
#include <WebCore/FloatQuad.h>
+#include <WebCore/FocusController.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/FrameTree.h>
#include <WebCore/FrameView.h>
#include <WebCore/FrameWin.h>
#include <WebCore/GDIObjectCounter.h>
#include <WebCore/GraphicsContext.h>
+#include <WebCore/HTMLMediaElement.h>
+#include <WebCore/HTMLNames.h>
#include <WebCore/HistoryItem.h>
#include <WebCore/HitTestRequest.h>
#include <WebCore/HitTestResult.h>
@@ -133,13 +137,13 @@
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#endif
-#include <wtf/HashSet.h>
+#include <ShlObj.h>
#include <comutil.h>
#include <dimm.h>
#include <oleacc.h>
-#include <ShlObj.h>
#include <tchar.h>
#include <windowsx.h>
+#include <wtf/HashSet.h>
// Soft link functions for gestures and panning feedback
SOFT_LINK_LIBRARY(USER32);
@@ -5656,6 +5660,40 @@ static KURL toKURL(BSTR bstr)
return KURL(KURL(), toString(bstr));
}
+void WebView::enterFullscreenForNode(Node* node)
+{
+ if (!node->hasTagName(HTMLNames::videoTag))
+ return;
+
+ HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
+
+ if (m_fullscreenController) {
+ if (m_fullscreenController->mediaElement() == videoElement) {
+ // The backend may just warn us that the underlaying plaftormMovie()
+ // has changed. Just force an update.
+ m_fullscreenController->setMediaElement(videoElement);
+ return; // No more to do.
+ }
+
+ // First exit Fullscreen for the old mediaElement.
+ m_fullscreenController->mediaElement()->exitFullscreen();
+ // This previous call has to trigger exitFullscreen,
+ // which has to clear m_fullscreenController.
+ ASSERT(!m_fullscreenController);
+ }
+
+ m_fullscreenController = new FullscreenVideoController;
+ m_fullscreenController->setMediaElement(videoElement);
+ m_fullscreenController->enterFullscreen();
+}
+
+void WebView::exitFullscreen()
+{
+ if (m_fullscreenController)
+ m_fullscreenController->exitFullscreen();
+ m_fullscreenController = 0;
+}
+
static PassOwnPtr<Vector<String> > toStringVector(unsigned patternsCount, BSTR* patterns)
{
// Convert the patterns into a Vector.
diff --git a/WebKit/win/WebView.h b/WebKit/win/WebView.h
index 9522ed3..88f656b 100644
--- a/WebKit/win/WebView.h
+++ b/WebKit/win/WebView.h
@@ -39,8 +39,9 @@
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
-class WebFrame;
+class FullscreenVideoController;
class WebBackForwardList;
+class WebFrame;
class WebInspector;
class WebInspectorClient;
@@ -868,6 +869,9 @@ public:
void setRootChildLayer(WebCore::PlatformLayer* layer);
#endif
+ void enterFullscreenForNode(WebCore::Node*);
+ void exitFullscreen();
+
private:
void setZoomMultiplier(float multiplier, bool isTextOnly);
float zoomMultiplier(bool isTextOnly);
@@ -984,6 +988,8 @@ protected:
long m_xOverpan;
long m_yOverpan;
+ OwnPtr<FullscreenVideoController> m_fullscreenController;
+
#if USE(ACCELERATED_COMPOSITING)
bool isAcceleratedCompositing() const { return m_isAcceleratedCompositing; }
void setAcceleratedCompositing(bool);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list