1e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block/* 2e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Copyright (C) 2010 Igalia S.L 3e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 4e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * This library is free software; you can redistribute it and/or 5e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * modify it under the terms of the GNU Library General Public 6e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * License as published by the Free Software Foundation; either 7e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * version 2 of the License, or (at your option) any later version. 8e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 9e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * This library is distributed in the hope that it will be useful, 10e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * but WITHOUT ANY WARRANTY; without even the implied warranty of 11e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Library General Public License for more details. 13e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * 14e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * You should have received a copy of the GNU Library General Public License 15e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * along with this library; see the file COPYING.LIB. If not, write to 16e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block * Boston, MA 02110-1301, USA. 18e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block */ 19e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 20e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "config.h" 21e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 22e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if ENABLE(VIDEO) 23e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 24e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "FullscreenVideoController.h" 25e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "GRefPtrGtk.h" 2768513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "GtkVersioning.h" 28e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "MediaPlayer.h" 29e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 30e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <gdk/gdk.h> 31e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <gdk/gdkkeysyms.h> 32e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <glib/gi18n-lib.h> 33e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <gst/gst.h> 34e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include <gtk/gtk.h> 35e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 36e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockusing namespace std; 37e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockusing namespace WebCore; 38e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 39e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define HUD_AUTO_HIDE_INTERVAL 3000 // 3 seconds 40e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define PROGRESS_BAR_UPDATE_INTERVAL 150 // 150ms 41e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define VOLUME_UP_OFFSET 0.05 // 5% 42e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define VOLUME_DOWN_OFFSET 0.05 // 5% 43e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 44e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// Use symbolic icons only if we build with GTK+-3 support. They could 45e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// be enabled for the GTK+2 build but we'd need to bump the required 46e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block// version to at least 2.22. 47e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if GTK_MAJOR_VERSION < 3 48e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define PLAY_ICON_NAME "media-playback-start" 49e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define PAUSE_ICON_NAME "media-playback-pause" 50e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define EXIT_FULLSCREEN_ICON_NAME "view-restore" 51e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#else 52e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define PLAY_ICON_NAME "media-playback-start-symbolic" 53e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define PAUSE_ICON_NAME "media-playback-pause-symbolic" 54e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#define EXIT_FULLSCREEN_ICON_NAME "view-restore-symbolic" 55e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif 56e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 57e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean hideHudCallback(FullscreenVideoController* controller) 58e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 59e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->hideHud(); 60e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return FALSE; 61e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 62e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 63e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean onFullscreenGtkMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event, FullscreenVideoController* controller) 64e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 65e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->showHud(true); 66e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return TRUE; 67e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 68e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 69e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void onFullscreenGtkActiveNotification(GtkWidget* widget, GParamSpec* property, FullscreenVideoController* controller) 70e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 71e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!gtk_window_is_active(GTK_WINDOW(widget))) 72e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->hideHud(); 73e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 74e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 75e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean onFullscreenGtkConfigureEvent(GtkWidget* widget, GdkEventConfigure* event, FullscreenVideoController* controller) 76e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 77e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->gtkConfigure(event); 78e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return TRUE; 79e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 80e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 81e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void onFullscreenGtkDestroy(GtkWidget* widget, FullscreenVideoController* controller) 82e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 83e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->exitFullscreen(); 84e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 85e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 86e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void togglePlayPauseActivated(GtkAction* action, FullscreenVideoController* controller) 87e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 88e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->togglePlay(); 89e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 90e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 91e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void exitFullscreenActivated(GtkAction* action, FullscreenVideoController* controller) 92e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 93e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->exitOnUserRequest(); 94e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 95e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 96e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean progressBarUpdateCallback(FullscreenVideoController* controller) 97e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 98e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return controller->updateHudProgressBar(); 99e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 100e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 101e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean timeScaleButtonPressed(GtkWidget* widget, GdkEventButton* event, FullscreenVideoController* controller) 102e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 103e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (event->type != GDK_BUTTON_PRESS) 104e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return FALSE; 105e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 106e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->beginSeek(); 107e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return FALSE; 108e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 109e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean timeScaleButtonReleased(GtkWidget* widget, GdkEventButton* event, FullscreenVideoController* controller) 111e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 112e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->endSeek(); 113e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return FALSE; 114e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 115e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 116e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void timeScaleValueChanged(GtkWidget* widget, FullscreenVideoController* controller) 117e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 118e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->doSeek(); 119e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 120e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 121e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic void volumeValueChanged(GtkScaleButton *button, gdouble value, FullscreenVideoController* controller) 122e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 123e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->setVolume(static_cast<float>(value)); 124e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 125e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 126e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid playerVolumeChangedCallback(GObject *element, GParamSpec *pspec, FullscreenVideoController* controller) 127e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 128e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->volumeChanged(); 129e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 130e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 131e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid playerMuteChangedCallback(GObject *element, GParamSpec *pspec, FullscreenVideoController* controller) 132e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 133e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->muteChanged(); 134e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 135e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 136e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockFullscreenVideoController::FullscreenVideoController() 137e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block : m_hudTimeoutId(0) 138e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_progressBarUpdateId(0) 139e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_seekLock(false) 140e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_window(0) 141e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block , m_hudWindow(0) 142e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 143e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 144e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 145e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockFullscreenVideoController::~FullscreenVideoController() 146e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 147e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block exitFullscreen(); 148e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 149e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 150e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement) 151e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 152e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (mediaElement == m_mediaElement) 153e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 154e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 155e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement = mediaElement; 156e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_mediaElement) { 157e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Can't do full-screen, just get out 158e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block exitFullscreen(); 159e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 160e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 161e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 162e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::gtkConfigure(GdkEventConfigure* event) 163e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 164e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block updateHudPosition(); 165e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 166e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 167e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::showHud(bool autoHide) 168e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 169e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_hudWindow) 170e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 171e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 172e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_hudTimeoutId) { 173e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_source_remove(m_hudTimeoutId); 174e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudTimeoutId = 0; 175e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 176e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 177e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Show the cursor. 178e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkWindow* window = gtk_widget_get_window(m_window); 179bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen gdk_window_set_cursor(window, 0); 180e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 181e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Update the progress bar immediately before showing the window. 182e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block updateHudProgressBar(); 183e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_widget_show_all(m_hudWindow); 184e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block updateHudPosition(); 185e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 186e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Start periodic updates of the progress bar. 187e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_progressBarUpdateId) 188e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_progressBarUpdateId = g_timeout_add(PROGRESS_BAR_UPDATE_INTERVAL, reinterpret_cast<GSourceFunc>(progressBarUpdateCallback), this); 189e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 190e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Hide the hud in few seconds, if requested. 191e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (autoHide) 192e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudTimeoutId = g_timeout_add(HUD_AUTO_HIDE_INTERVAL, reinterpret_cast<GSourceFunc>(hideHudCallback), this); 193e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 194e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 195e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::hideHud() 196e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 197e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_hudTimeoutId) { 198e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_source_remove(m_hudTimeoutId); 199e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudTimeoutId = 0; 200e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 201e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 202e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_hudWindow) 203e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 204e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 205e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Keep the hud visible if a seek is in progress or if the volume 206e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // popup is visible. 207e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GtkWidget* volumePopup = gtk_scale_button_get_popup(GTK_SCALE_BUTTON(m_volumeButton)); 208e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_seekLock || gtk_widget_get_visible(volumePopup)) { 209e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block showHud(true); 210e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 211e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 212e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 213e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkWindow* window = gtk_widget_get_window(m_window); 214bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen GdkCursor* cursor = blankCursor(); 215e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gdk_window_set_cursor(window, cursor); 216e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch gtk_widget_hide(m_hudWindow); 218e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 219e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_progressBarUpdateId) { 220e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_source_remove(m_progressBarUpdateId); 221e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_progressBarUpdateId = 0; 222e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 223e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 224e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 225e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic gboolean onFullscreenGtkKeyPressEvent(GtkWidget* widget, GdkEventKey* event, FullscreenVideoController* controller) 226e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 227e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block switch (event->keyval) { 228e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case GDK_Escape: 229e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case 'f': 230e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case 'F': 231e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->exitOnUserRequest(); 232e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 233e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case GDK_space: 234e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case GDK_Return: 235e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->togglePlay(); 236e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 237e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case GDK_Up: 238e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // volume up 239e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->setVolume(controller->volume() + VOLUME_UP_OFFSET); 240e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 241e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block case GDK_Down: 242e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // volume down 243e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block controller->setVolume(controller->volume() - VOLUME_DOWN_OFFSET); 244e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 245e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block default: 246e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block break; 247e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 248e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 249e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return TRUE; 250e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 251e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 252e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 253e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::enterFullscreen() 254e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 255e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_mediaElement) 256e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 257e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 258e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement->platformMedia().type != WebCore::PlatformMedia::GStreamerGWorldType) 259e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 260e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 261e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_gstreamerGWorld = m_mediaElement->platformMedia().media.gstreamerGWorld; 262e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_gstreamerGWorld->enterFullscreen()) 263e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 264e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 265e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_window = reinterpret_cast<GtkWidget*>(m_gstreamerGWorld->platformVideoWindow()->window()); 266e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 267e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GstElement* pipeline = m_gstreamerGWorld->pipeline(); 268e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(pipeline, "notify::volume", G_CALLBACK(playerVolumeChangedCallback), this); 269e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(pipeline, "notify::mute", G_CALLBACK(playerMuteChangedCallback), this); 270e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 271e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_hudWindow) 272e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block createHud(); 273e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 274e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Ensure black background. 27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef GTK_API_VERSION_2 27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch GdkColor color = { 1, 0, 0, 0 }; 277e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_widget_modify_bg(m_window, GTK_STATE_NORMAL, &color); 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch GdkRGBA color = { 0, 0, 0, 1}; 28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch gtk_widget_override_background_color(m_window, GTK_STATE_FLAG_NORMAL, &color); 28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 282e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_widget_set_double_buffered(m_window, FALSE); 283e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 284e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_window, "key-press-event", G_CALLBACK(onFullscreenGtkKeyPressEvent), this); 285e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_window, "destroy", G_CALLBACK(onFullscreenGtkDestroy), this); 286e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_window, "notify::is-active", G_CALLBACK(onFullscreenGtkActiveNotification), this); 287e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 288e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_widget_show_all(m_window); 289e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 290e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkWindow* window = gtk_widget_get_window(m_window); 29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch GRefPtr<GdkCursor> cursor(adoptGRef(blankCursor())); 29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch gdk_window_set_cursor(window, cursor.get()); 293e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 294e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_window, "motion-notify-event", G_CALLBACK(onFullscreenGtkMotionNotifyEvent), this); 295e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_window, "configure-event", G_CALLBACK(onFullscreenGtkConfigureEvent), this); 296e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 297e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_fullscreen(GTK_WINDOW(m_window)); 298e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block showHud(true); 299e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 300e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 301e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::updateHudPosition() 302e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 303e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_hudWindow) 304e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 305e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 306e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Get the screen rectangle. 307e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(m_window)); 308e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkWindow* window = gtk_widget_get_window(m_window); 309e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GdkRectangle fullscreenRectangle; 310e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gdk_screen_get_monitor_geometry(screen, gdk_screen_get_monitor_at_window(screen, window), 311e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block &fullscreenRectangle); 312e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 313e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Get the popup window size. 314e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int hudWidth, hudHeight; 315e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_get_size(GTK_WINDOW(m_hudWindow), &hudWidth, &hudHeight); 316e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 317e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Resize the hud to the full width of the screen. 318e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_resize(GTK_WINDOW(m_hudWindow), fullscreenRectangle.width, hudHeight); 319e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 320e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Move the hud to the bottom of the screen. 321e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_move(GTK_WINDOW(m_hudWindow), fullscreenRectangle.x, 322e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block fullscreenRectangle.height + fullscreenRectangle.y - hudHeight); 323e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 324e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 325e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::exitOnUserRequest() 326e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 327e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->exitFullscreen(); 328e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 329e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 330e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::exitFullscreen() 331e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 332e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_hudWindow) 333e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 334e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 335e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkKeyPressEvent), this); 336e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkDestroy), this); 337e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkMotionNotifyEvent), this); 338e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(m_window, reinterpret_cast<void*>(onFullscreenGtkConfigureEvent), this); 339e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 340e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GstElement* pipeline = m_mediaElement->platformMedia().media.gstreamerGWorld->pipeline(); 341e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(pipeline, reinterpret_cast<void*>(playerVolumeChangedCallback), this); 342e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handlers_disconnect_by_func(pipeline, reinterpret_cast<void*>(playerMuteChangedCallback), this); 343e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 344e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_hudTimeoutId) { 345e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_source_remove(m_hudTimeoutId); 346e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudTimeoutId = 0; 347e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 348e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 349e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_progressBarUpdateId) { 350e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_source_remove(m_progressBarUpdateId); 351e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_progressBarUpdateId = 0; 352e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 353e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 354e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement->platformMedia().type == WebCore::PlatformMedia::GStreamerGWorldType) 355e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->platformMedia().media.gstreamerGWorld->exitFullscreen(); 356e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 357a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch gtk_widget_hide(m_window); 358e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 359e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_widget_destroy(m_hudWindow); 360e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudWindow = 0; 361e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 362e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 363e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockbool FullscreenVideoController::canPlay() const 364e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 365e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement && m_mediaElement->canPlay(); 366e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 367e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 368e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::play() 369e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 370e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) 371e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->play(m_mediaElement->processingUserGesture()); 372e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 373e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block playStateChanged(); 374e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block showHud(true); 375e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 376e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 377e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::pause() 378e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 379e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) 380e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->pause(m_mediaElement->processingUserGesture()); 381e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 382e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block playStateChanged(); 383e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block showHud(false); 384e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 385e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 386e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::playStateChanged() 387e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 388e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (canPlay()) 389e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_object_set(m_playPauseAction, "tooltip", _("Play"), "icon-name", PLAY_ICON_NAME, NULL); 390e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 391e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_object_set(m_playPauseAction, "tooltip", _("Pause"), "icon-name", PAUSE_ICON_NAME, NULL); 392e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 393e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 394e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::togglePlay() 395e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 396e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (canPlay()) 397e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block play(); 398e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 399e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block pause(); 400e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 401e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 402e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockfloat FullscreenVideoController::volume() const 403e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 404e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement ? m_mediaElement->volume() : 0; 405e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 406e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 407e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockbool FullscreenVideoController::muted() const 408e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 409e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement ? m_mediaElement->muted() : false; 410e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 411e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 412e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::setVolume(float volume) 413e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 414e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (volume < 0.0 || volume > 1.0) 415e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 416e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 417e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) { 418e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ExceptionCode ec; 419e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->setVolume(volume, ec); 420e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 421e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 422e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 423e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::volumeChanged() 424e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 425e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handler_block(m_volumeButton, m_volumeUpdateId); 426e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), volume()); 427e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handler_unblock(m_volumeButton, m_volumeUpdateId); 428e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 429e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 430e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::muteChanged() 431e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 432e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handler_block(m_volumeButton, m_volumeUpdateId); 433e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), muted() ? 0 : volume()); 434e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_handler_unblock(m_volumeButton, m_volumeUpdateId); 435e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 436e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 437e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockfloat FullscreenVideoController::currentTime() const 438e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 439e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement ? m_mediaElement->currentTime() : 0; 440e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 441e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 442e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::setCurrentTime(float value) 443e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 444e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) { 445e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ExceptionCode ec; 446e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->setCurrentTime(value, ec); 447e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 448e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 449e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 450e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockfloat FullscreenVideoController::duration() const 451e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 452e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement ? m_mediaElement->duration() : 0; 453e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 454e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 455e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockfloat FullscreenVideoController::percentLoaded() const 456e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 457e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return m_mediaElement ? m_mediaElement->percentLoaded() : 0; 458e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 459e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 460e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::beginSeek() 461e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 462e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_seekLock = true; 463e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 464e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) 465e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->beginScrubbing(); 466e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 467e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 468e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::doSeek() 469e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 470e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_seekLock) 471e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return; 472e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 473e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block setCurrentTime(gtk_range_get_value(GTK_RANGE(m_timeHScale))*duration() / 100); 474e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 475e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 476e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::endSeek() 477e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 478e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_mediaElement) 479e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_mediaElement->endScrubbing(); 480e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 481e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_seekLock = false; 482e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 483e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 484e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockstatic String timeToString(float time) 485e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 486e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!isfinite(time)) 487e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block time = 0; 488e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int seconds = fabsf(time); 489e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int hours = seconds / (60 * 60); 490e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block int minutes = (seconds / 60) % 60; 491e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block seconds %= 60; 492e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 493e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (hours) { 494e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (hours > 9) 495e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); 496e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); 497e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 498e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 499e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds); 500e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 501e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 502e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockgboolean FullscreenVideoController::updateHudProgressBar() 503e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 504e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block float mediaDuration(duration()); 505e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block float mediaPosition(currentTime()); 506e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 507e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!m_seekLock) { 508e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gdouble value = 0.0; 509e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 510e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (mediaPosition && mediaDuration) 511e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block value = (mediaPosition * 100.0) / mediaDuration; 512e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 513e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(m_timeHScale)); 514e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_adjustment_set_value(adjustment, value); 515e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block } 516e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 517e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_range_set_fill_level(GTK_RANGE(m_timeHScale), percentLoaded()* 100); 518e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 519e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gchar* label = g_strdup_printf("%s / %s", timeToString(mediaPosition).utf8().data(), 520e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block timeToString(mediaDuration).utf8().data()); 521e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_label_set_text(GTK_LABEL(m_timeLabel), label); 522e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_free(label); 523e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block return TRUE; 524e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 525e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 526e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FullscreenVideoController::createHud() 527e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{ 528e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hudWindow = gtk_window_new(GTK_WINDOW_POPUP); 529e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_set_gravity(GTK_WINDOW(m_hudWindow), GDK_GRAVITY_SOUTH_WEST); 530e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_window_set_type_hint(GTK_WINDOW(m_hudWindow), GDK_WINDOW_TYPE_HINT_NORMAL); 531e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 532e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_hudWindow, "motion-notify-event", G_CALLBACK(onFullscreenGtkMotionNotifyEvent), this); 533e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 534e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GtkWidget* hbox = gtk_hbox_new(FALSE, 4); 535e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_container_add(GTK_CONTAINER(m_hudWindow), hbox); 536e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 537e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_playPauseAction = gtk_action_new("play", _("Play / Pause"), _("Play or pause the media"), PAUSE_ICON_NAME); 538e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_playPauseAction, "activate", G_CALLBACK(togglePlayPauseActivated), this); 539e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 540e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block playStateChanged(); 541e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 542e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GtkWidget* item = gtk_action_create_tool_item(m_playPauseAction); 543e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), item, FALSE, TRUE, 0); 544e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 545e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block GtkWidget* label = gtk_label_new(_("Time:")); 546e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); 547e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 548a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch GtkAdjustment* adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 100.0, 0.1, 1.0, 1.0)); 549a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_timeHScale = gtk_hscale_new(adjustment); 550e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_scale_set_draw_value(GTK_SCALE(m_timeHScale), FALSE); 551e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_range_set_show_fill_level(GTK_RANGE(m_timeHScale), TRUE); 552e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_timeHScale, "button-press-event", G_CALLBACK(timeScaleButtonPressed), this); 553e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_timeHScale, "button-release-event", G_CALLBACK(timeScaleButtonReleased), this); 554e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_hscaleUpdateId = g_signal_connect(m_timeHScale, "value-changed", G_CALLBACK(timeScaleValueChanged), this); 555e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 556e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), m_timeHScale, TRUE, TRUE, 0); 557e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 558e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_timeLabel = gtk_label_new(""); 559e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), m_timeLabel, FALSE, TRUE, 0); 560e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 561e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // Volume button. 562e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_volumeButton = gtk_volume_button_new(); 563e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), m_volumeButton, FALSE, TRUE, 0); 564e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_scale_button_set_value(GTK_SCALE_BUTTON(m_volumeButton), volume()); 565e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_volumeUpdateId = g_signal_connect(m_volumeButton, "value-changed", G_CALLBACK(volumeValueChanged), this); 566e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 567e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 568e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_exitFullscreenAction = gtk_action_new("exit", _("Exit Fullscreen"), _("Exit from fullscreen mode"), EXIT_FULLSCREEN_ICON_NAME); 569e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_signal_connect(m_exitFullscreenAction, "activate", G_CALLBACK(exitFullscreenActivated), this); 570e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block g_object_set(m_exitFullscreenAction, "icon-name", EXIT_FULLSCREEN_ICON_NAME, NULL); 571e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block item = gtk_action_create_tool_item(m_exitFullscreenAction); 572e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block gtk_box_pack_start(GTK_BOX(hbox), item, FALSE, TRUE, 0); 573e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 574e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 575e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_progressBarUpdateId = g_timeout_add(PROGRESS_BAR_UPDATE_INTERVAL, reinterpret_cast<GSourceFunc>(progressBarUpdateCallback), this); 576e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block} 577e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block 578e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif 579