Reviewed by Gustavo Noronha Silva.
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Aug 2010 08:04:50 +0000 (08:04 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Aug 2010 08:04:50 +0000 (08:04 +0000)
        [GStreamer] GTK XOverlay support in GStreamerGWorld
        https://bugs.webkit.org/show_bug.cgi?id=39474

        * configure.ac: gst-interfaces link support needed for use of
        GstXOverlay interface.
        * GNUmakefile.am: Added new FullscreenVideoController files in the
        build.

LayoutTests:

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] GTK XOverlay support in GStreamerGWorld
        https://bugs.webkit.org/show_bug.cgi?id=39474

        Rebaselined tests showing the video controls containing the new
        fullscreen button.

        * platform/gtk/media/controls-after-reload-expected.txt:
        * platform/gtk/media/controls-drag-timebar-expected.txt:
        * platform/gtk/media/controls-strict-expected.txt:
        * platform/gtk/media/controls-styling-expected.txt:
        * platform/gtk/media/video-controls-rendering-expected.txt:

WebCore:

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] GTK XOverlay support in GStreamerGWorld
        https://bugs.webkit.org/show_bug.cgi?id=39474

        GStreamerGWorld now catches synchronous messages coming from the
        sinks and creates a GTK window where the video can be overlayed if
        fullscreen display is requested using enterFullscreen.

        * GNUmakefile.am:
        * platform/graphics/gstreamer/GStreamerGWorld.cpp:
        (WebCore::gstGWorldSyncMessageCallback):
        (WebCore::GStreamerGWorld::GStreamerGWorld):
        (WebCore::GStreamerGWorld::~GStreamerGWorld):
        (WebCore::GStreamerGWorld::enterFullscreen):
        (WebCore::GStreamerGWorld::exitFullscreen):
        (WebCore::GStreamerGWorld::setWindowOverlay):
        * platform/graphics/gstreamer/GStreamerGWorld.h:
        (WebCore::GStreamerGWorld::pipeline):
        (WebCore::GStreamerGWorld::platformVideoWindow):
        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
        * platform/graphics/gstreamer/PlatformVideoWindow.h: Added.
        (WebCore::PlatformVideoWindow::createWindow):
        (WebCore::PlatformVideoWindow::window):
        (WebCore::PlatformVideoWindow::videoWindowId):
        * platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp: Added.
        (PlatformVideoWindow::PlatformVideoWindow):

WebKt/gtk:

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] GTK XOverlay support in GStreamerGWorld
        https://bugs.webkit.org/show_bug.cgi?id=39474

        New FullscreenVideoController object, private in the webview. It
        is created when the user presses the fullscreen button of the
        video controls. Video is displayed in fullscreen, controls are
        displayed when the user moves the mouse and when the video is
        paused. There's also basic keyboard shortcuts support: F/f to
        leave fullscreen, space to toggle play/pause and up/down to
        control volume.

        * WebCoreSupport/ChromeClientGtk.cpp:
        (WebKit::ChromeClient::supportsFullscreenForNode):
        (WebKit::ChromeClient::enterFullscreenForNode):
        (WebKit::ChromeClient::exitFullscreenForNode):
        * WebCoreSupport/ChromeClientGtk.h:
        * WebCoreSupport/FullscreenVideoController.cpp: Added.
        (hideHudCallback):
        (onFullscreenGtkMotionNotifyEvent):
        (onFullscreenGtkActiveNotification):
        (onFullscreenGtkConfigureEvent):
        (onFullscreenGtkDestroy):
        (togglePlayPauseActivated):
        (exitFullscreenActivated):
        (progressBarUpdateCallback):
        (timeScaleButtonPressed):
        (timeScaleButtonReleased):
        (timeScaleValueChanged):
        (volumeValueChanged):
        (playerVolumeChangedCallback):
        (playerMuteChangedCallback):
        (FullscreenVideoController::FullscreenVideoController):
        (FullscreenVideoController::~FullscreenVideoController):
        (FullscreenVideoController::setMediaElement):
        (FullscreenVideoController::gtkConfigure):
        (FullscreenVideoController::showHud):
        (FullscreenVideoController::hideHud):
        (onFullscreenGtkKeyPressEvent):
        (FullscreenVideoController::enterFullscreen):
        (FullscreenVideoController::updateHudPosition):
        (FullscreenVideoController::exitOnUserRequest):
        (FullscreenVideoController::exitFullscreen):
        (FullscreenVideoController::canPlay):
        (FullscreenVideoController::play):
        (FullscreenVideoController::pause):
        (FullscreenVideoController::playStateChanged):
        (FullscreenVideoController::togglePlay):
        (FullscreenVideoController::volume):
        (FullscreenVideoController::muted):
        (FullscreenVideoController::setVolume):
        (FullscreenVideoController::volumeChanged):
        (FullscreenVideoController::muteChanged):
        (FullscreenVideoController::currentTime):
        (FullscreenVideoController::setCurrentTime):
        (FullscreenVideoController::duration):
        (FullscreenVideoController::percentLoaded):
        (FullscreenVideoController::beginSeek):
        (FullscreenVideoController::doSeek):
        (FullscreenVideoController::endSeek):
        (timeToString):
        (FullscreenVideoController::updateHudProgressBar):
        (FullscreenVideoController::createHud):
        * WebCoreSupport/FullscreenVideoController.h: Added.
        (FullscreenVideoController::mediaElement):
        * webkit/webkitprivate.cpp:
        (webkit_web_view_enter_fullscreen):
        (webkit_web_view_exit_fullscreen):
        * webkit/webkitprivate.h:

WebKit/gtk/po:

        Reviewed by Gustavo Noronha Silva.

        [GStreamer] GTK XOverlay support in GStreamerGWorld
        https://bugs.webkit.org/show_bug.cgi?id=39474

        * POTFILES: Added new file that contains strings to extract.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@65658 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
ChangeLog
GNUmakefile.am
LayoutTests/ChangeLog
LayoutTests/platform/gtk/media/controls-after-reload-expected.txt
LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt
LayoutTests/platform/gtk/media/controls-strict-expected.txt
LayoutTests/platform/gtk/media/controls-styling-expected.txt
LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt
LayoutTests/platform/gtk/media/video-display-toggle-expected.txt
LayoutTests/platform/gtk/media/video-no-audio-expected.txt
LayoutTests/platform/gtk/media/video-zoom-controls-expected.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h [new file with mode: 0644]
WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp [new file with mode: 0644]
WebKit/gtk/ChangeLog
WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp [new file with mode: 0644]
WebKit/gtk/WebCoreSupport/FullscreenVideoController.h [new file with mode: 0644]
WebKit/gtk/po/ChangeLog
WebKit/gtk/po/POTFILES
WebKit/gtk/webkit/webkitprivate.cpp
WebKit/gtk/webkit/webkitprivate.h
configure.ac

index 3b7f414..0ed45f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2010-08-19  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GStreamer] GTK XOverlay support in GStreamerGWorld
+        https://bugs.webkit.org/show_bug.cgi?id=39474
+
+        * configure.ac: gst-interfaces link support needed for use of
+        GstXOverlay interface.
+        * GNUmakefile.am: Added new FullscreenVideoController files in the
+        build.
+
 2010-08-18  Lucas De Marchi  <lucas.demarchi@profusion.mobi>
 
         Reviewed by Antonio Gomes.
index 42d6673..87b9564 100644 (file)
@@ -749,6 +749,8 @@ webkitgtk_sources += \
        WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp \
        WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h \
        WebKit/gtk/WebCoreSupport/FrameNetworkingContextGtk.h \
+       WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp \
+       WebKit/gtk/WebCoreSupport/FullscreenVideoController.h \
        WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp \
        WebKit/gtk/WebCoreSupport/InspectorClientGtk.h \
        WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.cpp \
index 1235143..84dfabf 100644 (file)
@@ -1,3 +1,19 @@
+2010-08-19  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GStreamer] GTK XOverlay support in GStreamerGWorld
+        https://bugs.webkit.org/show_bug.cgi?id=39474
+
+        Rebaselined tests showing the video controls containing the new
+        fullscreen button.
+
+        * platform/gtk/media/controls-after-reload-expected.txt:
+        * platform/gtk/media/controls-drag-timebar-expected.txt:
+        * platform/gtk/media/controls-strict-expected.txt:
+        * platform/gtk/media/controls-styling-expected.txt:
+        * platform/gtk/media/video-controls-rendering-expected.txt:
+
 2010-08-19  Ryosuke Niwa  <rniwa@webkit.org>
 
         Reviewed by Tony Chang.
index a0bae18..f776eb0 100644 (file)
@@ -15,9 +15,10 @@ layer at (8,44) size 320x240
 layer at (8,264) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
index 6936be4..a41211a 100644 (file)
@@ -4,10 +4,10 @@ RUN(video.autoplay = true)
 RUN(video.src = 'content/test.mp4')
 EVENT(playing)
 EVENT(seeked)
-Time: 2.1
+Time: 2.4
 EVENT(seeked)
-Time: 2.7
+Time: 3.0
 EVENT(seeked)
-Time: 3.2
+Time: 3.6
 END OF TEST
 
index be3615b..3f96d03 100644 (file)
@@ -15,9 +15,10 @@ layer at (8,52) size 320x240
 layer at (8,272) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
index fe941df..bf8513a 100644 (file)
@@ -19,9 +19,10 @@ layer at (18,44) size 320x240
 layer at (18,264) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
@@ -30,9 +31,10 @@ layer at (8,284) size 320x240
 layer at (8,504) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
index ec8c14f..e4b7eb1 100644 (file)
@@ -20,9 +20,10 @@ layer at (8,44) size 320x240
 layer at (8,264) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
@@ -31,9 +32,10 @@ layer at (8,284) size 320x240
 layer at (8,504) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
@@ -44,9 +46,10 @@ layer at (8,524) size 320x240
 layer at (8,744) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
index 19e092f..00c3a58 100644 (file)
@@ -14,9 +14,10 @@ layer at (8,28) size 320x240
 layer at (8,248) size 320x20
   RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 238x20
+    RenderFlexibleBox {DIV} at (20,0) size 220x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 218x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (240,0) size 20x20
     RenderButton {INPUT} at (260,0) size 20x20
     RenderButton {INPUT} at (280,0) size 20x20
     RenderButton {INPUT} at (300,0) size 20x20
index cdc6cee..2f45e54 100644 (file)
@@ -15,8 +15,9 @@ layer at (8,44) size 352x288
 layer at (8,312) size 352x20
   RenderFlexibleBox (positioned) {DIV} at (0,268) size 352x20
     RenderButton {INPUT} at (0,0) size 20x20
-    RenderFlexibleBox {DIV} at (20,0) size 292x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 290x20
+    RenderFlexibleBox {DIV} at (20,0) size 272x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 270x20
         RenderBlock {DIV} at (2,4) size 12x12
+    RenderButton {INPUT} at (292,0) size 20x20
     RenderButton {INPUT} at (312,0) size 20x20
     RenderButton {INPUT} at (332,0) size 20x20
index 8221d55..d3f74d5 100644 (file)
@@ -13,9 +13,10 @@ layer at (57,87) size 240x180
 layer at (57,237) size 240x30
   RenderFlexibleBox (positioned) {DIV} at (0,150) size 240x30
     RenderButton {INPUT} at (0,0) size 30x30
-    RenderFlexibleBox {DIV} at (30,0) size 120x30 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 118x30
+    RenderFlexibleBox {DIV} at (30,0) size 90x30 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 88x30
         RenderBlock {DIV} at (3,9) size 12x12
+    RenderButton {INPUT} at (120,0) size 30x30
     RenderButton {INPUT} at (150,0) size 30x30
     RenderButton {INPUT} at (180,0) size 30x30
     RenderButton {INPUT} at (210,0) size 30x30
@@ -26,9 +27,10 @@ layer at (57,312) size 240x180
 layer at (57,462) size 240x30
   RenderFlexibleBox (positioned) {DIV} at (0,150) size 240x30
     RenderButton {INPUT} at (0,0) size 30x30
-    RenderFlexibleBox {DIV} at (30,0) size 120x30 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
-      RenderSlider {INPUT} at (1,0) size 118x30
+    RenderFlexibleBox {DIV} at (30,0) size 90x30 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
+      RenderSlider {INPUT} at (1,0) size 88x30
         RenderBlock {DIV} at (3,9) size 12x12
+    RenderButton {INPUT} at (120,0) size 30x30
     RenderButton {INPUT} at (150,0) size 30x30
     RenderButton {INPUT} at (180,0) size 30x30
     RenderButton {INPUT} at (210,0) size 30x30
index a0f21b9..948da4a 100644 (file)
@@ -1,3 +1,33 @@
+2010-08-19  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GStreamer] GTK XOverlay support in GStreamerGWorld
+        https://bugs.webkit.org/show_bug.cgi?id=39474
+
+        GStreamerGWorld now catches synchronous messages coming from the
+        sinks and creates a GTK window where the video can be overlayed if
+        fullscreen display is requested using enterFullscreen.
+
+        * GNUmakefile.am:
+        * platform/graphics/gstreamer/GStreamerGWorld.cpp:
+        (WebCore::gstGWorldSyncMessageCallback):
+        (WebCore::GStreamerGWorld::GStreamerGWorld):
+        (WebCore::GStreamerGWorld::~GStreamerGWorld):
+        (WebCore::GStreamerGWorld::enterFullscreen):
+        (WebCore::GStreamerGWorld::exitFullscreen):
+        (WebCore::GStreamerGWorld::setWindowOverlay):
+        * platform/graphics/gstreamer/GStreamerGWorld.h:
+        (WebCore::GStreamerGWorld::pipeline):
+        (WebCore::GStreamerGWorld::platformVideoWindow):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        * platform/graphics/gstreamer/PlatformVideoWindow.h: Added.
+        (WebCore::PlatformVideoWindow::createWindow):
+        (WebCore::PlatformVideoWindow::window):
+        (WebCore::PlatformVideoWindow::videoWindowId):
+        * platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp: Added.
+        (PlatformVideoWindow::PlatformVideoWindow):
+
 2010-08-19  Eric Uhrhane  <ericu@chromium.org>
 
         Reviewed by David Levin.
index 99c0547..20baf0f 100644 (file)
@@ -3170,6 +3170,8 @@ webcoregtk_sources += \
        WebCore/platform/graphics/gstreamer/GStreamerGWorld.h \
        WebCore/platform/graphics/gstreamer/ImageGStreamer.h \
        WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp \
+       WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h \
+       WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp \
        WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp \
        WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
 
index c5022f9..b29479d 100644 (file)
 
 #include "GStreamerGWorld.h"
 
-#include "MediaPlayerPrivateGStreamer.h"
+#include "GOwnPtrGStreamer.h"
+
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h> // for GDK_WINDOW_XID
+#endif
+#endif
 
 using namespace std;
 
 namespace WebCore {
 
+gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data)
+{
+    ASSERT(GST_MESSAGE_TYPE(message) == GST_MESSAGE_ELEMENT);
+
+    GStreamerGWorld* gstGWorld = static_cast<GStreamerGWorld*>(data);
+
+    if (gst_structure_has_name(message->structure, "prepare-xwindow-id"))
+        gstGWorld->setWindowOverlay(message);
+    return TRUE;
+}
+
 PassRefPtr<GStreamerGWorld> GStreamerGWorld::createGWorld(MediaPlayerPrivateGStreamer* player)
 {
     return adoptRef(new GStreamerGWorld(player));
@@ -34,11 +55,145 @@ PassRefPtr<GStreamerGWorld> GStreamerGWorld::createGWorld(MediaPlayerPrivateGStr
 
 GStreamerGWorld::GStreamerGWorld(MediaPlayerPrivateGStreamer* player)
     : m_player(player)
+    , m_dynamicPadName(0)
 {
+    // XOverlay messages need to be handled synchronously.
+    GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_player->pipeline()));
+    gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, this);
+    g_signal_connect(bus, "sync-message::element", G_CALLBACK(gstGWorldSyncMessageCallback), this);
+    gst_object_unref(bus);
 }
 
 GStreamerGWorld::~GStreamerGWorld()
 {
+    exitFullscreen();
+}
+
+bool GStreamerGWorld::enterFullscreen()
+{
+    if (m_dynamicPadName)
+        return false;
+
+    if (!m_videoWindow)
+        m_videoWindow = PlatformVideoWindow::createWindow();
+
+    GstElement* pipeline = m_player->pipeline();
+    GstElement* platformVideoSink = gst_element_factory_make("autovideosink", "platformVideoSink");
+    GstElement* colorspace = gst_element_factory_make("ffmpegcolorspace", "colorspace");
+    GstElement* queue = gst_element_factory_make("queue", "queue");
+    GstElement* videoScale = gst_element_factory_make("videoscale", "videoScale");
+
+    // Get video sink bin and the tee inside.
+    GOwnPtr<GstElement> videoSink;
+    g_object_get(pipeline, "video-sink", &videoSink.outPtr(), NULL);
+    GstElement* tee = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoTee");
+
+    // Add and link a queue, ffmpegcolorspace and sink in the bin.
+    gst_bin_add_many(GST_BIN(videoSink.get()), platformVideoSink, videoScale, colorspace, queue, NULL);
+    gst_element_link_many(queue, colorspace, videoScale, platformVideoSink, NULL);
+
+    // Link a new src pad from tee to queue.
+    GstPad* srcPad = gst_element_get_request_pad(tee, "src%d");
+    GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
+    gst_pad_link(srcPad, sinkPad);
+    gst_object_unref(GST_OBJECT(sinkPad));
+
+    m_dynamicPadName = gst_pad_get_name(srcPad);
+
+    // Roll new elements to pipeline state.
+    gst_element_sync_state_with_parent(queue);
+    gst_element_sync_state_with_parent(colorspace);
+    gst_element_sync_state_with_parent(videoScale);
+    gst_element_sync_state_with_parent(platformVideoSink);
+
+    gst_object_unref(tee);
+
+    // Query the current media segment informations and send them towards
+    // the new tee branch downstream.
+
+    GstQuery* query = gst_query_new_segment(GST_FORMAT_TIME);
+    gboolean queryResult = gst_element_query(pipeline, query);
+
+    // See https://bugzilla.gnome.org/show_bug.cgi?id=620490.
+#if GST_CHECK_VERSION(0, 10, 30)
+    if (!queryResult) {
+        gst_query_unref(query);
+        gst_object_unref(GST_OBJECT(srcPad));
+        return true;
+    }
+#endif
+
+    GstFormat format;
+    gint64 position;
+    if (!gst_element_query_position(pipeline, &format, &position))
+        position = 0;
+
+    gdouble rate;
+    gint64 startValue, stopValue;
+    gst_query_parse_segment(query, &rate, &format, &startValue, &stopValue);
+
+    GstEvent* event = gst_event_new_new_segment(FALSE, rate, format, startValue, stopValue, position);
+    gst_pad_push_event(srcPad, event);
+
+    gst_query_unref(query);
+    gst_object_unref(GST_OBJECT(srcPad));
+    return true;
+}
+
+void GStreamerGWorld::exitFullscreen()
+{
+    if (!m_dynamicPadName)
+        return;
+
+    GstElement* pipeline = m_player->pipeline();
+
+    // Get video sink bin and the elements to remove.
+    GOwnPtr<GstElement> videoSink;
+    g_object_get(pipeline, "video-sink", &videoSink.outPtr(), NULL);
+    GstElement* tee = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoTee");
+    GstElement* platformVideoSink = gst_bin_get_by_name(GST_BIN(videoSink.get()), "platformVideoSink");
+    GstElement* queue = gst_bin_get_by_name(GST_BIN(videoSink.get()), "queue");
+    GstElement* colorspace = gst_bin_get_by_name(GST_BIN(videoSink.get()), "colorspace");
+    GstElement* videoScale = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoScale");
+
+    // Get pads to unlink and remove.
+    GstPad* srcPad = gst_element_get_static_pad(tee, m_dynamicPadName);
+    GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
+
+    // Unlink and release request pad.
+    gst_pad_unlink(srcPad, sinkPad);
+    gst_element_release_request_pad(tee, srcPad);
+    gst_object_unref(GST_OBJECT(srcPad));
+    gst_object_unref(GST_OBJECT(sinkPad));
+
+    // Unlink, remove and cleanup queue, ffmpegcolorspace, videoScale and sink.
+    gst_element_unlink_many(queue, colorspace, videoScale, platformVideoSink, NULL);
+    gst_bin_remove_many(GST_BIN(videoSink.get()), queue, colorspace, videoScale, platformVideoSink, NULL);
+    gst_element_set_state(queue, GST_STATE_NULL);
+    gst_element_set_state(colorspace, GST_STATE_NULL);
+    gst_element_set_state(videoScale, GST_STATE_NULL);
+    gst_element_set_state(platformVideoSink, GST_STATE_NULL);
+    gst_object_unref(queue);
+    gst_object_unref(colorspace);
+    gst_object_unref(videoScale);
+    gst_object_unref(platformVideoSink);
+
+    gst_object_unref(tee);
+    m_dynamicPadName = 0;
+}
+
+void GStreamerGWorld::setWindowOverlay(GstMessage* message)
+{
+    GstObject* sink = GST_MESSAGE_SRC(message);
+
+    if (!GST_IS_X_OVERLAY(sink))
+        return;
+
+    if (g_object_class_find_property(G_OBJECT_GET_CLASS(sink), "force-aspect-ratio"))
+        g_object_set(sink, "force-aspect-ratio", TRUE, NULL);
+
+    if (m_videoWindow)
+        gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId());
 }
 
 }
index b626298..0358b01 100644 (file)
 
 #if ENABLE(VIDEO)
 
+#include "MediaPlayerPrivateGStreamer.h"
+#include "PlatformVideoWindow.h"
 #include "RefCounted.h"
 #include "RefPtr.h"
 #include <glib.h>
 
+typedef struct _GstElement GstElement;
+typedef struct _GstMessage GstMessage;
+typedef struct _GstBus GstBus;
+typedef struct _GstBin GstBin;
 
 namespace WebCore {
 
 class MediaPlayerPrivateGStreamer;
 
+gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
 
 class GStreamerGWorld : public RefCounted<GStreamerGWorld> {
+    friend gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
 
 public:
     static PassRefPtr<GStreamerGWorld> createGWorld(MediaPlayerPrivateGStreamer*);
     ~GStreamerGWorld();
 
+    GstElement* pipeline() const { return m_player->pipeline(); }
+
+    // Returns the full-screen window created
+    bool enterFullscreen();
+    void exitFullscreen();
+
+    void setWindowOverlay(GstMessage* message);
+    PlatformVideoWindow* platformVideoWindow() const { return m_videoWindow.get(); }
+
 private:
     GStreamerGWorld(MediaPlayerPrivateGStreamer*);
     MediaPlayerPrivateGStreamer* m_player;
+    RefPtr<PlatformVideoWindow> m_videoWindow;
+    gchar* m_dynamicPadName;
 };
 
 }
index 7184439..9fff984 100644 (file)
@@ -54,7 +54,6 @@
 #include <GOwnPtr.h>
 #include <gst/gst.h>
 #include <gst/interfaces/mixer.h>
-#include <gst/interfaces/xoverlay.h>
 #include <gst/video/video.h>
 #include <limits>
 #include <math.h>
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
new file mode 100644 (file)
index 0000000..83dc5dd
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PlatformVideoWindow_h
+#define PlatformVideoWindow_h
+
+#if ENABLE(VIDEO)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+typedef GtkWidget PlatformWindowType;
+#endif
+
+namespace WebCore {
+
+class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
+    public:
+        static PassRefPtr<PlatformVideoWindow> createWindow() { return adoptRef(new PlatformVideoWindow()); }
+
+        PlatformVideoWindow();
+        ~PlatformVideoWindow();
+
+        PlatformWindowType* window() const { return m_window; }
+        gulong videoWindowId() const { return m_videoWindowId; }
+
+    private:
+        gulong m_videoWindowId;
+        PlatformWindowType* m_videoWindow;
+        PlatformWindowType* m_window;
+    };
+}
+
+#endif
+
+#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
new file mode 100644 (file)
index 0000000..185f535
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "PlatformVideoWindow.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h> // for GDK_WINDOW_XID
+#endif
+
+using namespace WebCore;
+
+PlatformVideoWindow::PlatformVideoWindow()
+{
+    m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_events(m_window, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_FOCUS_CHANGE_MASK);
+
+    m_videoWindow = gtk_drawing_area_new();
+    gtk_widget_set_double_buffered(m_videoWindow, FALSE);
+    gtk_container_add(GTK_CONTAINER(m_window), m_videoWindow);
+
+    gtk_widget_realize(m_window);
+
+#ifdef GDK_WINDOWING_X11
+    m_videoWindowId = GDK_WINDOW_XID(gtk_widget_get_window(m_window));
+#endif
+
+}
+
+PlatformVideoWindow::~PlatformVideoWindow()
+{
+    if (m_videoWindow && m_window) {
+        gtk_container_remove(GTK_CONTAINER(m_window), m_videoWindow);
+        gtk_widget_destroy(m_videoWindow);
+        m_videoWindow = 0;
+    }
+
+    if (m_window) {
+        gtk_widget_destroy(m_window);
+        m_window = 0;
+    }
+
+    m_videoWindowId = 0;
+}
index 79e4a0b..2863a52 100644 (file)
@@ -1,3 +1,76 @@
+2010-08-19  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GStreamer] GTK XOverlay support in GStreamerGWorld
+        https://bugs.webkit.org/show_bug.cgi?id=39474
+
+        New FullscreenVideoController object, private in the webview. It
+        is created when the user presses the fullscreen button of the
+        video controls. Video is displayed in fullscreen, controls are
+        displayed when the user moves the mouse and when the video is
+        paused. There's also basic keyboard shortcuts support: F/f to
+        leave fullscreen, space to toggle play/pause and up/down to
+        control volume.
+
+        * WebCoreSupport/ChromeClientGtk.cpp:
+        (WebKit::ChromeClient::supportsFullscreenForNode):
+        (WebKit::ChromeClient::enterFullscreenForNode):
+        (WebKit::ChromeClient::exitFullscreenForNode):
+        * WebCoreSupport/ChromeClientGtk.h:
+        * WebCoreSupport/FullscreenVideoController.cpp: Added.
+        (hideHudCallback):
+        (onFullscreenGtkMotionNotifyEvent):
+        (onFullscreenGtkActiveNotification):
+        (onFullscreenGtkConfigureEvent):
+        (onFullscreenGtkDestroy):
+        (togglePlayPauseActivated):
+        (exitFullscreenActivated):
+        (progressBarUpdateCallback):
+        (timeScaleButtonPressed):
+        (timeScaleButtonReleased):
+        (timeScaleValueChanged):
+        (volumeValueChanged):
+        (playerVolumeChangedCallback):
+        (playerMuteChangedCallback):
+        (FullscreenVideoController::FullscreenVideoController):
+        (FullscreenVideoController::~FullscreenVideoController):
+        (FullscreenVideoController::setMediaElement):
+        (FullscreenVideoController::gtkConfigure):
+        (FullscreenVideoController::showHud):
+        (FullscreenVideoController::hideHud):
+        (onFullscreenGtkKeyPressEvent):
+        (FullscreenVideoController::enterFullscreen):
+        (FullscreenVideoController::updateHudPosition):
+        (FullscreenVideoController::exitOnUserRequest):
+        (FullscreenVideoController::exitFullscreen):
+        (FullscreenVideoController::canPlay):
+        (FullscreenVideoController::play):
+        (FullscreenVideoController::pause):
+        (FullscreenVideoController::playStateChanged):
+        (FullscreenVideoController::togglePlay):
+        (FullscreenVideoController::volume):
+        (FullscreenVideoController::muted):
+        (FullscreenVideoController::setVolume):
+        (FullscreenVideoController::volumeChanged):
+        (FullscreenVideoController::muteChanged):
+        (FullscreenVideoController::currentTime):
+        (FullscreenVideoController::setCurrentTime):
+        (FullscreenVideoController::duration):
+        (FullscreenVideoController::percentLoaded):
+        (FullscreenVideoController::beginSeek):
+        (FullscreenVideoController::doSeek):
+        (FullscreenVideoController::endSeek):
+        (timeToString):
+        (FullscreenVideoController::updateHudProgressBar):
+        (FullscreenVideoController::createHud):
+        * WebCoreSupport/FullscreenVideoController.h: Added.
+        (FullscreenVideoController::mediaElement):
+        * webkit/webkitprivate.cpp:
+        (webkit_web_view_enter_fullscreen):
+        (webkit_web_view_exit_fullscreen):
+        * webkit/webkitprivate.h:
+
 2010-08-18  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
 
         Reviewed by Martin Robinson.
index 185ac16..077d9cb 100644 (file)
@@ -30,6 +30,7 @@
 #include "FloatRect.h"
 #include "FrameLoadRequest.h"
 #include "GtkVersioning.h"
+#include "HTMLNames.h"
 #include "IntRect.h"
 #include "HitTestResult.h"
 #include "Icon.h"
@@ -641,4 +642,28 @@ PassRefPtr<WebCore::SearchPopupMenu> ChromeClient::createSearchPopupMenu(WebCore
     return adoptRef(new SearchPopupMenuGtk(client));
 }
 
+#if ENABLE(VIDEO)
+
+bool ChromeClient::supportsFullscreenForNode(const Node* node)
+{
+    return node->hasTagName(HTMLNames::videoTag);
+}
+
+void ChromeClient::enterFullscreenForNode(Node* node)
+{
+    WebCore::Frame* frame = node->document()->frame();
+    WebKitWebFrame* webFrame = kit(frame);
+    WebKitWebView* webView = getViewFromFrame(webFrame);
+    webkitWebViewEnterFullscreen(webView, node);
+}
+
+void ChromeClient::exitFullscreenForNode(Node* node)
+{
+    WebCore::Frame* frame = node->document()->frame();
+    WebKitWebFrame* webFrame = kit(frame);
+    WebKitWebView* webView = getViewFromFrame(webFrame);
+    webkitWebViewExitFullscreen(webView);
+}
+#endif
+
 }
index e3be1c2..21c4677 100644 (file)
@@ -133,6 +133,11 @@ namespace WebKit {
         virtual bool selectItemWritingDirectionIsNatural();
         virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const;
         virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const;
+#if ENABLE(VIDEO)
+        virtual bool supportsFullscreenForNode(const WebCore::Node*);
+        virtual void enterFullscreenForNode(WebCore::Node*);
+        virtual void exitFullscreenForNode(WebCore::Node*);
+#endif
 
     private:
         WebKitWebView* m_webView;
diff --git a/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp b/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp
new file mode 100644 (file)
index 0000000..c95dcff
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ *  Copyright (C) 2010 Igalia S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+
+#include "FullscreenVideoController.h"
+
+#include "MediaPlayer.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n-lib.h>
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+
+using namespace std;
+using namespace WebCore;
+
+#define HUD_AUTO_HIDE_INTERVAL 3000 // 3 seconds
+#define PROGRESS_BAR_UPDATE_INTERVAL 150 // 150ms
+#define VOLUME_UP_OFFSET 0.05 // 5%
+#define VOLUME_DOWN_OFFSET 0.05 // 5%
+
+// Use symbolic icons only if we build with GTK+-3 support. They could
+// be enabled for the GTK+2 build but we'd need to bump the required
+// version to at least 2.22.
+#if GTK_MAJOR_VERSION < 3
+#define PLAY_ICON_NAME "media-playback-start"
+#define PAUSE_ICON_NAME "media-playback-pause"
+#define EXIT_FULLSCREEN_ICON_NAME "view-restore"
+#else
+#define PLAY_ICON_NAME "media-playback-start-symbolic"
+#define PAUSE_ICON_NAME "media-playback-pause-symbolic"
+#define EXIT_FULLSCREEN_ICON_NAME "view-restore-symbolic"
+#endif
+
+static gboolean hideHudCallback(FullscreenVideoController* controller)
+{
+    controller->hideHud();
+    return FALSE;
+}
+
+static gboolean onFullscreenGtkMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event,  FullscreenVideoController* controller)
+{
+    controller->showHud(true);
+    return TRUE;
+}
+
+static void onFullscreenGtkActiveNotification(GtkWidget* widget, GParamSpec* property, FullscreenVideoController* controller)
+{
+    if (!gtk_window_is_active(GTK_WINDOW(widget)))
+        controller->hideHud();
+}
+
+static gboolean onFullscreenGtkConfigureEvent(GtkWidget* widget, GdkEventConfigure* event, FullscreenVideoController* controller)
+{
+    controller->gtkConfigure(event);
+    return TRUE;
+}
+
+static void onFullscreenGtkDestroy(GtkWidget* widget, FullscreenVideoController* controller)
+{
+    controller->exitFullscreen();
+}
+
+static void togglePlayPauseActivated(GtkAction* action, FullscreenVideoController* controller)
+{
+    controller->togglePlay();
+}
+
+static void exitFullscreenActivated(GtkAction* action, FullscreenVideoController* controller)
+{
+    controller->exitOnUserRequest();
+}
+
+static gboolean progressBarUpdateCallback(FullscreenVideoController* controller)
+{
+    return controller->updateHudProgressBar();
+}
+
+static gboolean timeScaleButtonPressed(GtkWidget* widget, GdkEventButton* event, FullscreenVideoController* controller)
+{
+    if (event->type != GDK_BUTTON_PRESS)
+        return FALSE;
+
+    controller->beginSeek();
+    return FALSE;
+}
+
+static gboolean timeScaleButtonReleased(GtkWidget* widget, GdkEventButton* event, FullscreenVideoController* controller)
+{
+    controller->endSeek();
+    return FALSE;
+}
+
+static void timeScaleValueChanged(GtkWidget* widget, FullscreenVideoController* controller)
+{
+    controller->doSeek();
+}
+
+static void volumeValueChanged(GtkScaleButton *button, gdouble value, FullscreenVideoController* controller)
+{
+    controller->setVolume(static_cast<float>(value));
+}
+
+void playerVolumeChangedCallback(GObject *element, GParamSpec *pspec, FullscreenVideoController* controller)
+{
+    controller->volumeChanged();
+}
+
+void playerMuteChangedCallback(GObject *element, GParamSpec *pspec, FullscreenVideoController* controller)
+{
+    controller->muteChanged();
+}
+
+FullscreenVideoController::FullscreenVideoController()
+    : m_hudTimeoutId(0)
+    , m_progressBarUpdateId(0)
+    , m_seekLock(false)
+    , m_window(0)
+    , m_hudWindow(0)
+{
+}
+
+FullscreenVideoController::~FullscreenVideoController()
+{
+    exitFullscreen();
+}
+
+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::gtkConfigure(GdkEventConfigure* event)
+{
+    updateHudPosition();
+}
+
+void FullscreenVideoController::showHud(bool autoHide)
+{
+    if (!m_hudWindow)
+        return;
+
+    if (m_hudTimeoutId) {
+        g_source_remove(m_hudTimeoutId);
+        m_hudTimeoutId = 0;
+    }
+
+    // Show the cursor.
+    GdkWindow* window = gtk_widget_get_window(m_window);
+    gdk_window_set_cursor(window, m_cursor.get());
+
+    // Update the progress bar immediately before showing the window.
+    updateHudProgressBar();
+    gtk_widget_show_all(m_hudWindow);
+    updateHudPosition();
+
+    // Start periodic updates of the progress bar.
+    if (!m_progressBarUpdateId)
+        m_progressBarUpdateId = g_timeout_add(PROGRESS_BAR_UPDATE_INTERVAL, reinterpret_cast<GSourceFunc>(progressBarUpdateCallback), this);
+
+    // Hide the hud in few seconds, if requested.
+    if (autoHide)
+        m_hudTimeoutId = g_timeout_add(HUD_AUTO_HIDE_INTERVAL, reinterpret_cast<GSourceFunc>(hideHudCallback), this);
+}
+
+void FullscreenVideoController::hideHud()
+{
+    if (m_hudTimeoutId) {
+        g_source_remove(m_hudTimeoutId);
+        m_hudTimeoutId = 0;
+    }
+
+    if (!m_hudWindow)
+        return;
+
+    // Keep the hud visible if a seek is in progress or if the volume
+    // popup is visible.
+    GtkWidget* volumePopup = gtk_scale_button_get_popup(GTK_SCALE_BUTTON(m_volumeButton));
+    if (m_seekLock || gtk_widget_get_visible(volumePopup)) {
+        showHud(true);
+        return;
+    }
+
+    GdkWindow* window = gtk_widget_get_window(m_window);
+    GdkCursor* cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
+    gdk_window_set_cursor(window, cursor);
+
+    gtk_widget_hide_all(m_hudWindow);
+
+    if (m_progressBarUpdateId) {
+        g_source_remove(m_progressBarUpdateId);
+        m_progressBarUpdateId = 0;
+    }
+}
+
+static gboolean onFullscreenGtkKeyPressEvent(GtkWidget* widget, GdkEventKey* event, FullscreenVideoController* controller)
+{
+    switch (event->keyval) {
+    case GDK_Escape:
+    case 'f':
+    case 'F':
+        controller->exitOnUserRequest();
+        break;
+    case GDK_space:
+    case GDK_Return:
+        controller->togglePlay();
+        break;
+    case GDK_Up:
+        // volume up
+        controller->setVolume(controller->volume() + VOLUME_UP_OFFSET);
+        break;
+    case GDK_Down:
+        // volume down
+        controller->setVolume(controller->volume() - VOLUME_DOWN_OFFSET);
+        break;
+    default:
+        break;
+    }
+
+    return TRUE;
+}
+
+
+void FullscreenVideoController::enterFullscreen()
+{
+    if (!m_mediaElement)
+        return;
+
+    if (m_mediaElement->platformMedia().type != WebCore::PlatformMedia::GStreamerGWorldType)
+        return;
+
+    m_gstreamerGWorld = m_mediaElement->platformMedia().media.gstreamerGWorld;
+    if (!m_gstreamerGWorld->enterFullscreen())
+        return;
+
+    m_window = reinterpret_cast<GtkWidget*>(m_gstreamerGWorld->platformVideoWindow()->window());
+
+    GstElement* pipeline = m_gstreamerGWorld->pipeline();
+    g_signal_connect(pipeline, "notify::volume", G_CALLBACK(playerVolumeChangedCallback), this);
+    g_signal_connect(pipeline, "notify::mute", G_CALLBACK(playerMuteChangedCallback), this);
+
+    if (!m_hudWindow)
+        createHud();
+
+    // Ensure black background.
+    GdkColor color;
+    gdk_color_parse("black", &color);
+    gtk_widget_modify_bg(m_window, GTK_STATE_NORMAL, &color);
+    gtk_widget_set_double_buffered(m_window, FALSE);
+
+    g_signal_connect(m_window, "key-press-event", G_CALLBACK(onFullscreenGtkKeyPressEvent), this);
+    g_signal_connect(m_window, "destroy", G_CALLBACK(onFullscreenGtkDestroy), this);
+    g_signal_connect(m_window, "notify::is-active", G_CALLBACK(onFullscreenGtkActiveNotification), this);
+
+    gtk_widget_show_all(m_window);
+
+    GdkWindow* window = gtk_widget_get_window(m_window);
+    GdkCursor* cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
+    m_cursor = gdk_window_get_cursor(window);
+    gdk_window_set_cursor(window, cursor);
+    gdk_cursor_unref(cursor);
+
+    g_signal_connect(m_window, "motion-notify-event", G_CALLBACK(onFullscreenGtkMotionNotifyEvent), this);
+    g_signal_connect(m_window, "configure-event", G_CALLBACK(onFullscreenGtkConfigureEvent), this);
+
+    gtk_window_fullscreen(GTK_WINDOW(m_window));
+    showHud(true);
+}
+
+void FullscreenVideoController::updateHudPosition()
+{
+    if (!m_hudWindow)
+        return;
+
+    // Get the screen rectangle.
+    GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(m_window));
+    GdkWindow* window = gtk_widget_get_window(m_window);
+    GdkRectangle fullscreenRectangle;
+    gdk_screen_get_monitor_geometry(screen, gdk_screen_get_monitor_at_window(screen, window),
+                                    &fullscreenRectangle);
+
+    // Get the popup window size.
+    int hudWidth, hudHeight;
+    gtk_window_get_size(GTK_WINDOW(m_hudWindow), &hudWidth, &hudHeight);
+
+    // Resize the hud to the full width of the screen.
+    gtk_window_resize(GTK_WINDOW(m_hudWindow), fullscreenRectangle.width, hudHeight);
+
+    // Move the hud to the bottom of the screen.
+    gtk_window_move(GTK_WINDOW(m_hudWindow), fullscreenRectangle.x,
+                    fullscreenRectangle.height + fullscreenRectangle.y - hudHeight);
+}
+
+void FullscreenVideoController::exitOnUserRequest()
+{
+    m_mediaElement->exitFullscreen();
+}
+
+void FullscreenVideoController::exitFullscreen()
+{
+    if (!m_hudWindow)
+        return;
+
+    g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkKeyPressEvent), this);
+    g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkDestroy), this);
+    g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkMotionNotifyEvent), this);
+    g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkConfigureEvent), this);
+
+    GstElement* pipeline = m_mediaElement->platformMedia().media.gstreamerGWorld->pipeline();
+    g_signal_handlers_disconnect_by_func(pipeline, reinterpret_cast<void*>(playerVolumeChangedCallback), this);
+    g_signal_handlers_disconnect_by_func(pipeline, reinterpret_cast<void*>(playerMuteChangedCallback), this);
+
+    if (m_hudTimeoutId) {
+        g_source_remove(m_hudTimeoutId);
+        m_hudTimeoutId = 0;
+    }
+
+    if (m_progressBarUpdateId) {
+        g_source_remove(m_progressBarUpdateId);
+        m_progressBarUpdateId = 0;
+    }
+
+    if (m_mediaElement->platformMedia().type == WebCore::PlatformMedia::GStreamerGWorldType)
+        m_mediaElement->platformMedia().media.gstreamerGWorld->exitFullscreen();
+
+    gtk_widget_hide_all(m_window);
+
+    gtk_widget_destroy(m_hudWindow);
+    m_hudWindow = 0;
+}
+
+bool FullscreenVideoController::canPlay() const
+{
+    return m_mediaElement && m_mediaElement->canPlay();
+}
+
+void FullscreenVideoController::play()
+{
+    if (m_mediaElement)
+        m_mediaElement->play(m_mediaElement->processingUserGesture());
+
+    playStateChanged();
+    showHud(true);
+}
+
+void FullscreenVideoController::pause()
+{
+    if (m_mediaElement)
+        m_mediaElement->pause(m_mediaElement->processingUserGesture());
+
+    playStateChanged();
+    showHud(false);
+}
+
+void FullscreenVideoController::playStateChanged()
+{
+    if (canPlay())
+        g_object_set(m_playPauseAction, "tooltip", _("Play"), "icon-name", PLAY_ICON_NAME, NULL);
+    else
+        g_object_set(m_playPauseAction, "tooltip", _("Pause"), "icon-name", PAUSE_ICON_NAME, NULL);
+}
+
+void FullscreenVideoController::togglePlay()
+{
+    if (canPlay())
+        play();
+    else
+        pause();
+}
+
+float FullscreenVideoController::volume() const
+{
+    return m_mediaElement ? m_mediaElement->volume() : 0;
+}
+
+bool FullscreenVideoController::muted() const
+{
+    return m_mediaElement ? m_mediaElement->muted() : false;
+}
+
+void FullscreenVideoController::setVolume(float volume)
+{
+    if (volume < 0.0 || volume > 1.0)
+        return;
+
+    if (m_mediaElement) {
+        ExceptionCode ec;
+        m_mediaElement->setVolume(volume, ec);
+    }
+}
+
+void FullscreenVideoController::volumeChanged()
+{
+    g_signal_handler_block(m_volumeButton, m_volumeUpdateId);
+    gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), volume());
+    g_signal_handler_unblock(m_volumeButton, m_volumeUpdateId);
+}
+
+void FullscreenVideoController::muteChanged()
+{
+    g_signal_handler_block(m_volumeButton, m_volumeUpdateId);
+    gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), muted() ? 0 : volume());
+    g_signal_handler_unblock(m_volumeButton, m_volumeUpdateId);
+}
+
+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;
+}
+
+float FullscreenVideoController::percentLoaded() const
+{
+    return m_mediaElement ? m_mediaElement->percentLoaded() : 0;
+}
+
+void FullscreenVideoController::beginSeek()
+{
+    m_seekLock = true;
+
+    if (m_mediaElement)
+        m_mediaElement->beginScrubbing();
+}
+
+void FullscreenVideoController::doSeek()
+{
+    if (!m_seekLock)
+         return;
+
+    setCurrentTime(gtk_range_get_value(GTK_RANGE(m_timeHScale))*duration() / 100);
+}
+
+void FullscreenVideoController::endSeek()
+{
+    if (m_mediaElement)
+        m_mediaElement->endScrubbing();
+
+    m_seekLock = false;
+}
+
+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);
+}
+
+gboolean FullscreenVideoController::updateHudProgressBar()
+{
+    float mediaDuration(duration());
+    float mediaPosition(currentTime());
+
+    if (!m_seekLock) {
+        gdouble value = 0.0;
+
+        if (mediaPosition && mediaDuration)
+            value = (mediaPosition * 100.0) / mediaDuration;
+
+        GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(m_timeHScale));
+        gtk_adjustment_set_value(adjustment, value);
+    }
+
+    gtk_range_set_fill_level(GTK_RANGE(m_timeHScale), percentLoaded()* 100);
+
+    gchar* label = g_strdup_printf("%s / %s", timeToString(mediaPosition).utf8().data(),
+                                   timeToString(mediaDuration).utf8().data());
+    gtk_label_set_text(GTK_LABEL(m_timeLabel), label);
+    g_free(label);
+    return TRUE;
+}
+
+void FullscreenVideoController::createHud()
+{
+    m_hudWindow = gtk_window_new(GTK_WINDOW_POPUP);
+    gtk_window_set_gravity(GTK_WINDOW(m_hudWindow), GDK_GRAVITY_SOUTH_WEST);
+    gtk_window_set_type_hint(GTK_WINDOW(m_hudWindow), GDK_WINDOW_TYPE_HINT_NORMAL);
+
+    g_signal_connect(m_hudWindow, "motion-notify-event", G_CALLBACK(onFullscreenGtkMotionNotifyEvent), this);
+
+    GtkWidget* hbox = gtk_hbox_new(FALSE, 4);
+    gtk_container_add(GTK_CONTAINER(m_hudWindow), hbox);
+
+    m_playPauseAction = gtk_action_new("play", _("Play / Pause"), _("Play or pause the media"), PAUSE_ICON_NAME);
+    g_signal_connect(m_playPauseAction, "activate", G_CALLBACK(togglePlayPauseActivated), this);
+
+    playStateChanged();
+
+    GtkWidget* item = gtk_action_create_tool_item(m_playPauseAction);
+    gtk_box_pack_start(GTK_BOX(hbox), item, FALSE, TRUE, 0);
+
+    GtkWidget* label = gtk_label_new(_("Time:"));
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+
+    GtkObject* adjustment = gtk_adjustment_new(0.0, 0.0, 100.0, 0.1, 1.0, 1.0);
+    m_timeHScale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+    gtk_scale_set_draw_value(GTK_SCALE(m_timeHScale), FALSE);
+    gtk_range_set_show_fill_level(GTK_RANGE(m_timeHScale), TRUE);
+    gtk_range_set_update_policy(GTK_RANGE(m_timeHScale), GTK_UPDATE_CONTINUOUS);
+    g_signal_connect(m_timeHScale, "button-press-event", G_CALLBACK(timeScaleButtonPressed), this);
+    g_signal_connect(m_timeHScale, "button-release-event", G_CALLBACK(timeScaleButtonReleased), this);
+    m_hscaleUpdateId = g_signal_connect(m_timeHScale, "value-changed", G_CALLBACK(timeScaleValueChanged), this);
+
+    gtk_box_pack_start(GTK_BOX(hbox), m_timeHScale, TRUE, TRUE, 0);
+
+    m_timeLabel = gtk_label_new("");
+    gtk_box_pack_start(GTK_BOX(hbox), m_timeLabel, FALSE, TRUE, 0);
+
+    // Volume button.
+    m_volumeButton = gtk_volume_button_new();
+    gtk_box_pack_start(GTK_BOX(hbox), m_volumeButton, FALSE, TRUE, 0);
+    gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), volume());
+    m_volumeUpdateId = g_signal_connect(m_volumeButton, "value-changed", G_CALLBACK(volumeValueChanged), this);
+
+
+    m_exitFullscreenAction = gtk_action_new("exit", _("Exit Fullscreen"), _("Exit from fullscreen mode"), EXIT_FULLSCREEN_ICON_NAME);
+    g_signal_connect(m_exitFullscreenAction, "activate", G_CALLBACK(exitFullscreenActivated), this);
+    g_object_set(m_exitFullscreenAction, "icon-name", EXIT_FULLSCREEN_ICON_NAME, NULL);
+    item = gtk_action_create_tool_item(m_exitFullscreenAction);
+    gtk_box_pack_start(GTK_BOX(hbox), item, FALSE, TRUE, 0);
+
+
+    m_progressBarUpdateId = g_timeout_add(PROGRESS_BAR_UPDATE_INTERVAL, reinterpret_cast<GSourceFunc>(progressBarUpdateCallback), this);
+}
+
+#endif
diff --git a/WebKit/gtk/WebCoreSupport/FullscreenVideoController.h b/WebKit/gtk/WebCoreSupport/FullscreenVideoController.h
new file mode 100644 (file)
index 0000000..31b7ff0
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  Copyright (C) 2010 Igalia S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FullscreenVideoController_h
+#define FullscreenVideoController_h
+
+#if ENABLE(VIDEO)
+
+#include "GRefPtr.h"
+#include "GStreamerGWorld.h"
+#include "HTMLMediaElement.h"
+#include <wtf/RefPtr.h>
+
+typedef struct _GtkObject GtkObject;
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkAction GtkAction;
+typedef struct _GdkCursor GdkCursor;
+typedef struct _GdkEventConfigure GdkEventConfigure;
+
+
+class FullscreenVideoController : public Noncopyable {
+public:
+    FullscreenVideoController();
+    virtual ~FullscreenVideoController();
+
+    void setMediaElement(WebCore::HTMLMediaElement*);
+    WebCore::HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); }
+
+    void gtkConfigure(GdkEventConfigure* event);
+
+    void enterFullscreen();
+    void exitFullscreen();
+
+    void exitOnUserRequest();
+    void togglePlay();
+    void beginSeek();
+    void doSeek();
+    void endSeek();
+
+    void hideHud();
+    void showHud(bool);
+    gboolean updateHudProgressBar();
+
+    float volume() const;
+    void setVolume(float);
+    void volumeChanged();
+    void muteChanged();
+
+private:
+    bool canPlay() const;
+    void play();
+    void pause();
+    void playStateChanged();
+
+    bool muted() const;
+
+    float currentTime() const;
+    void setCurrentTime(float);
+
+    float duration() const;
+    float percentLoaded() const;
+
+    void createHud();
+    void updateHudPosition();
+
+    RefPtr<WebCore::HTMLMediaElement> m_mediaElement;
+    RefPtr<WebCore::GStreamerGWorld> m_gstreamerGWorld;
+
+    guint m_hudTimeoutId;
+    guint m_progressBarUpdateId;
+    guint m_progressBarFillUpdateId;
+    guint m_hscaleUpdateId;
+    guint m_volumeUpdateId;
+    bool m_seekLock;
+    GtkWidget* m_window;
+    GRefPtr<GdkCursor> m_cursor;
+    GtkWidget* m_hudWindow;
+    GtkAction* m_playPauseAction;
+    GtkAction* m_exitFullscreenAction;
+    GtkWidget* m_timeHScale;
+    GtkWidget* m_timeLabel;
+    GtkWidget* m_volumeButton;
+};
+
+#endif
+
+#endif // FullscreenVideoController_h
index f088275..309ba09 100644 (file)
@@ -1,3 +1,12 @@
+2010-08-19  Philippe Normand  <pnormand@igalia.com>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GStreamer] GTK XOverlay support in GStreamerGWorld
+        https://bugs.webkit.org/show_bug.cgi?id=39474
+
+        * POTFILES: Added new file that contains strings to extract.
+
 2010-08-03 Jorge Gonz├ílez  <aloriel@gmail.com>
 
         Reviewed by Gustavo Noronha.
index 05ba138..ffd0015 100644 (file)
@@ -1,6 +1,7 @@
 # List of source files which contain translatable strings.
 WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
 WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp
+WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp
 WebKit/gtk/webkit/webkitdownload.cpp
 WebKit/gtk/webkit/webkitsoupauthdialog.c
 WebKit/gtk/webkit/webkitwebframe.cpp
index 91b2904..2dd4b18 100644 (file)
@@ -28,6 +28,8 @@
 #include "FrameLoader.h"
 #include "FrameLoaderClientGtk.h"
 #include "GtkVersioning.h"
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
 #include "HitTestResult.h"
 #include "IconDatabase.h"
 #include "Logging.h"
 #include <stdlib.h>
 #include <wtf/Threading.h>
 
+#if ENABLE(VIDEO)
+#include "FullscreenVideoController.h"
+#endif
+
 #if ENABLE(DATABASE)
 #include "DatabaseTracker.h"
 #endif
@@ -327,3 +333,33 @@ void webkit_reset_origin_access_white_lists()
 {
     SecurityOrigin::resetOriginAccessWhitelists();
 }
+
+
+void webkitWebViewEnterFullscreen(WebKitWebView* webView, Node* node)
+{
+    if (!node->hasTagName(HTMLNames::videoTag))
+        return;
+
+#if ENABLE(VIDEO)
+    HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
+    WebKitWebViewPrivate* priv = webView->priv;
+
+    // First exit Fullscreen for the old mediaElement.
+    if (priv->fullscreenVideoController)
+        priv->fullscreenVideoController->exitFullscreen();
+
+    priv->fullscreenVideoController = new FullscreenVideoController;
+    priv->fullscreenVideoController->setMediaElement(videoElement);
+    priv->fullscreenVideoController->enterFullscreen();
+#endif
+}
+
+void webkitWebViewExitFullscreen(WebKitWebView* webView)
+{
+#if ENABLE(VIDEO)
+    WebKitWebViewPrivate* priv = webView->priv;
+    if (priv->fullscreenVideoController)
+        priv->fullscreenVideoController->exitFullscreen();
+#endif
+}
+
index a5508a4..92bb27d 100644 (file)
@@ -56,6 +56,8 @@
 #include "InspectorClientGtk.h"
 #include "IntPoint.h"
 #include "FrameLoaderClient.h"
+#include "FullscreenVideoController.h"
+#include "Node.h"
 #include "Page.h"
 #include "ResourceHandle.h"
 #include "ResourceRequest.h"
@@ -161,6 +163,8 @@ extern "C" {
         gboolean disposing;
         gboolean usePrimaryForPaste;
 
+        FullscreenVideoController* fullscreenVideoController;
+
         // These are hosted here because the DataSource object is
         // created too late in the frame loading process.
         WebKitWebResource* mainResource;
@@ -410,6 +414,9 @@ extern "C" {
 
     WEBKIT_API void
     webkit_web_frame_layout(WebKitWebFrame* frame);
+
+    void webkitWebViewEnterFullscreen(WebKitWebView* webView, WebCore::Node* node);
+    void webkitWebViewExitFullscreen(WebKitWebView* webView);
 }
 
 #endif
index 0de8985..bc30d54 100644 (file)
@@ -841,6 +841,7 @@ if test "$enable_video" = "yes"; then
                      [gstreamer-0.10 >= $GSTREAMER_REQUIRED_VERSION
                      gstreamer-app-0.10
                      gstreamer-base-0.10
+                     gstreamer-interfaces-0.10
                      gstreamer-pbutils-0.10
                      gstreamer-plugins-base-0.10 >= $GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION
                      gstreamer-video-0.10])