summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/qmediaplayer/mediaplayer.cpp210
-rw-r--r--demos/qmediaplayer/mediaplayer.h45
-rw-r--r--demos/qmediaplayer/settings.ui351
-rw-r--r--src/3rdparty/phonon/mmf/mmf_videoplayer.cpp73
-rw-r--r--src/3rdparty/phonon/mmf/mmf_videoplayer.h7
-rw-r--r--src/3rdparty/phonon/mmf/objectdump_symbian.cpp2
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.cpp23
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.h6
-rw-r--r--src/gui/kernel/qapplication_s60.cpp42
-rw-r--r--src/gui/kernel/qwidget_p.h42
-rw-r--r--src/gui/kernel/qwidget_s60.cpp3
-rw-r--r--src/s60installs/s60installs.pro2
12 files changed, 525 insertions, 281 deletions
diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp
index f8ca8ea..8f6848f 100644
--- a/demos/qmediaplayer/mediaplayer.cpp
+++ b/demos/qmediaplayer/mediaplayer.cpp
@@ -47,109 +47,114 @@
#include "ui_settings.h"
-class MediaVideoWidget : public Phonon::VideoWidget
+MediaVideoWidget::MediaVideoWidget(MediaPlayer *player, QWidget *parent) :
+ Phonon::VideoWidget(parent), m_player(player), m_action(this)
+{
+ m_action.setCheckable(true);
+ m_action.setChecked(false);
+ m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return));
+ m_action.setShortcutContext(Qt::WindowShortcut);
+ connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool)));
+ addAction(&m_action);
+ setAcceptDrops(true);
+}
+
+void MediaVideoWidget::setFullScreen(bool enabled)
{
-public:
- MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0) :
- Phonon::VideoWidget(parent), m_player(player), m_action(this)
- {
- m_action.setCheckable(true);
- m_action.setChecked(false);
- m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return));
- m_action.setShortcutContext(Qt::WindowShortcut);
- connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool)));
- addAction(&m_action);
- setAcceptDrops(true);
- }
+ Phonon::VideoWidget::setFullScreen(enabled);
+ emit fullScreenChanged(enabled);
+}
-protected:
- void mouseDoubleClickEvent(QMouseEvent *e)
- {
- Phonon::VideoWidget::mouseDoubleClickEvent(e);
- setFullScreen(!isFullScreen());
- }
+void MediaVideoWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ Phonon::VideoWidget::mouseDoubleClickEvent(e);
+ setFullScreen(!isFullScreen());
+}
- void keyPressEvent(QKeyEvent *e)
- {
- if (e->key() == Qt::Key_Space && !e->modifiers()) {
+void MediaVideoWidget::keyPressEvent(QKeyEvent *e)
+{
+ if(!e->modifiers()) {
+ // On non-QWERTY Symbian key-based devices, there is no space key.
+ // The zero key typically is marked with a space character.
+ if (e->key() == Qt::Key_Space || e->key() == Qt::Key_0) {
m_player->playPause();
e->accept();
return;
- } else if (e->key() == Qt::Key_Escape && !e->modifiers()) {
+ }
+
+ // On Symbian devices, there is no key which maps to Qt::Key_Escape
+ // On devices which lack a backspace key (i.e. non-QWERTY devices),
+ // the 'C' key maps to Qt::Key_Backspace
+ else if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Backspace) {
setFullScreen(false);
e->accept();
return;
}
- Phonon::VideoWidget::keyPressEvent(e);
}
+ Phonon::VideoWidget::keyPressEvent(e);
+}
- bool event(QEvent *e)
+bool MediaVideoWidget::event(QEvent *e)
+{
+ switch(e->type())
{
- switch(e->type())
- {
- case QEvent::Close:
- //we just ignore the cose events on the video widget
- //this prevents ALT+F4 from having an effect in fullscreen mode
- e->ignore();
- return true;
- case QEvent::MouseMove:
+ case QEvent::Close:
+ //we just ignore the cose events on the video widget
+ //this prevents ALT+F4 from having an effect in fullscreen mode
+ e->ignore();
+ return true;
+ case QEvent::MouseMove:
#ifndef QT_NO_CURSOR
- unsetCursor();
+ unsetCursor();
#endif
- //fall through
- case QEvent::WindowStateChange:
- {
- //we just update the state of the checkbox, in case it wasn't already
- m_action.setChecked(windowState() & Qt::WindowFullScreen);
- const Qt::WindowFlags flags = m_player->windowFlags();
- if (windowState() & Qt::WindowFullScreen) {
- m_timer.start(1000, this);
- } else {
- m_timer.stop();
+ //fall through
+ case QEvent::WindowStateChange:
+ {
+ //we just update the state of the checkbox, in case it wasn't already
+ m_action.setChecked(windowState() & Qt::WindowFullScreen);
+ const Qt::WindowFlags flags = m_player->windowFlags();
+ if (windowState() & Qt::WindowFullScreen) {
+ m_timer.start(1000, this);
+ } else {
+ m_timer.stop();
#ifndef QT_NO_CURSOR
- unsetCursor();
+ unsetCursor();
#endif
- }
}
- break;
- default:
- break;
}
-
- return Phonon::VideoWidget::event(e);
+ break;
+ default:
+ break;
}
- void timerEvent(QTimerEvent *e)
- {
- if (e->timerId() == m_timer.timerId()) {
- //let's store the cursor shape
+ return Phonon::VideoWidget::event(e);
+}
+
+void MediaVideoWidget::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == m_timer.timerId()) {
+ //let's store the cursor shape
#ifndef QT_NO_CURSOR
- setCursor(Qt::BlankCursor);
+ setCursor(Qt::BlankCursor);
#endif
- }
- Phonon::VideoWidget::timerEvent(e);
- }
-
- void dropEvent(QDropEvent *e)
- {
- m_player->handleDrop(e);
}
+ Phonon::VideoWidget::timerEvent(e);
+}
- void dragEnterEvent(QDragEnterEvent *e) {
- if (e->mimeData()->hasUrls())
- e->acceptProposedAction();
- }
+void MediaVideoWidget::dropEvent(QDropEvent *e)
+{
+ m_player->handleDrop(e);
+}
-private:
- MediaPlayer *m_player;
- QBasicTimer m_timer;
- QAction m_action;
-};
+void MediaVideoWidget::dragEnterEvent(QDragEnterEvent *e) {
+ if (e->mimeData()->hasUrls())
+ e->acceptProposedAction();
+}
MediaPlayer::MediaPlayer(const QString &filePath,
const bool hasSmallScreen) :
- playButton(0), nextEffect(0), settingsDialog(0), ui(0),
+ playButton(0), nextEffect(0), settingsDialog(0), ui(0),
m_AudioOutput(Phonon::VideoCategory),
m_videoWidget(new MediaVideoWidget(this)),
m_hasSmallScreen(hasSmallScreen)
@@ -300,24 +305,32 @@ MediaPlayer::MediaPlayer(const QString &filePath,
QAction *scaleActionCrop = scaleMenu->addAction(tr("Scale and crop"));
scaleActionCrop->setCheckable(true);
scaleGroup->addAction(scaleActionCrop);
-
- fileMenu->addSeparator();
+
+ m_fullScreenAction = fileMenu->addAction(tr("Full screen video"));
+ m_fullScreenAction->setCheckable(true);
+ m_fullScreenAction->setEnabled(false); // enabled by hasVideoChanged
+ bool b = connect(m_fullScreenAction, SIGNAL(toggled(bool)), m_videoWidget, SLOT(setFullScreen(bool)));
+ Q_ASSERT(b);
+ b = connect(m_videoWidget, SIGNAL(fullScreenChanged(bool)), m_fullScreenAction, SLOT(setChecked(bool)));
+ Q_ASSERT(b);
+
+ fileMenu->addSeparator();
QAction *settingsAction = fileMenu->addAction(tr("&Settings..."));
-
+
// Setup signal connections:
connect(rewindButton, SIGNAL(clicked()), this, SLOT(rewind()));
//connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));
openButton->setMenu(fileMenu);
-
+
connect(playButton, SIGNAL(clicked()), this, SLOT(playPause()));
connect(forwardButton, SIGNAL(clicked()), this, SLOT(forward()));
//connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));
connect(settingsAction, SIGNAL(triggered(bool)), this, SLOT(showSettingsDialog()));
connect(openUrlAction, SIGNAL(triggered(bool)), this, SLOT(openUrl()));
connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(openFile()));
-
- connect(m_videoWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint)));
- connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint)));
+
+ connect(m_videoWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
connect(&m_MediaObject, SIGNAL(metaDataChanged()), this, SLOT(updateInfo()));
connect(&m_MediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(updateTime()));
connect(&m_MediaObject, SIGNAL(tick(qint64)), this, SLOT(updateTime()));
@@ -366,12 +379,12 @@ void MediaPlayer::stateChanged(Phonon::State newstate, Phonon::State oldstate)
}
QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close);
break;
- case Phonon::PausedState:
- case Phonon::StoppedState:
- playButton->setIcon(playIcon);
+ case Phonon::StoppedState:
m_videoWidget->setFullScreen(false);
-
+ // Fall through
+ case Phonon::PausedState:
+ playButton->setIcon(playIcon);
if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){
playButton->setEnabled(true);
rewindButton->setEnabled(true);
@@ -474,7 +487,7 @@ void MediaPlayer::effectChanged()
void MediaPlayer::showSettingsDialog()
{
- playPauseForDialog();
+ const bool hasPausedForDialog = playPauseForDialog();
if (!settingsDialog)
initSettingsDialog();
@@ -522,7 +535,8 @@ void MediaPlayer::showSettingsDialog()
ui->audioEffectsCombo->setCurrentIndex(currentEffect);
}
- playPauseForDialog();
+ if (hasPausedForDialog)
+ m_MediaObject.play();
}
void MediaPlayer::initVideoWindow()
@@ -659,24 +673,29 @@ void MediaPlayer::setFile(const QString &fileName)
m_MediaObject.play();
}
-void MediaPlayer::playPauseForDialog()
+bool MediaPlayer::playPauseForDialog()
{
- // If we're running on a small screen, we want to pause the video
- // when popping up dialogs.
- if (m_hasSmallScreen &&
- (Phonon::PlayingState == m_MediaObject.state() ||
- Phonon::PausedState == m_MediaObject.state()))
- playPause();
+ // If we're running on a small screen, we want to pause the video when
+ // popping up dialogs. We neither want to tamper with the state if the
+ // user has paused.
+ if (m_hasSmallScreen && m_MediaObject.hasVideo()) {
+ if (Phonon::PlayingState == m_MediaObject.state()) {
+ m_MediaObject.pause();
+ return true;
+ }
+ }
+ return false;
}
void MediaPlayer::openFile()
{
- playPauseForDialog();
+ const bool hasPausedForDialog = playPauseForDialog();
QStringList fileNames = QFileDialog::getOpenFileNames(this, QString(),
QDesktopServices::storageLocation(QDesktopServices::MusicLocation));
- playPauseForDialog();
+ if (hasPausedForDialog)
+ m_MediaObject.play();
m_MediaObject.clearQueue();
if (fileNames.size() > 0) {
@@ -916,4 +935,5 @@ void MediaPlayer::hasVideoChanged(bool bHasVideo)
{
info->setVisible(!bHasVideo);
m_videoWindow.setVisible(bHasVideo);
+ m_fullScreenAction->setEnabled(bHasVideo);
}
diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h
index a8f18f0..14ed4ac 100644
--- a/demos/qmediaplayer/mediaplayer.h
+++ b/demos/qmediaplayer/mediaplayer.h
@@ -47,6 +47,8 @@
#include <QtCore/QTimerEvent>
#include <QtGui/QShowEvent>
#include <QtGui/QIcon>
+#include <QtCore/QBasicTimer>
+#include <QtGui/QAction>
#include <Phonon/AudioOutput>
#include <Phonon/BackendCapabilities>
@@ -67,6 +69,36 @@ class QMenu;
class Ui_settings;
QT_END_NAMESPACE
+class MediaPlayer;
+
+class MediaVideoWidget : public Phonon::VideoWidget
+{
+ Q_OBJECT
+
+public:
+ MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0);
+
+public slots:
+ // Over-riding non-virtual Phonon::VideoWidget slot
+ void setFullScreen(bool);
+
+signals:
+ void fullScreenChanged(bool);
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ bool event(QEvent *e);
+ void timerEvent(QTimerEvent *e);
+ void dropEvent(QDropEvent *e);
+ void dragEnterEvent(QDragEnterEvent *e);
+
+private:
+ MediaPlayer *m_player;
+ QBasicTimer m_timer;
+ QAction m_action;
+};
+
class MediaPlayer :
public QWidget
{
@@ -74,7 +106,7 @@ class MediaPlayer :
public:
MediaPlayer(const QString &,
const bool hasSmallScreen);
-
+
void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e);
void dropEvent(QDropEvent *e);
@@ -82,7 +114,7 @@ public:
void setFile(const QString &text);
void initVideoWindow();
void initSettingsDialog();
-
+
public slots:
void openFile();
void rewind();
@@ -104,7 +136,7 @@ private slots:
void stateChanged(Phonon::State newstate, Phonon::State oldstate);
void effectChanged();
void showSettingsDialog();
- void showContextMenu(const QPoint &);
+ void showContextMenu(const QPoint& point);
void bufferStatus(int percent);
void openUrl();
void openRamFile();
@@ -112,7 +144,7 @@ private slots:
void hasVideoChanged(bool);
private:
- void playPauseForDialog();
+ bool playPauseForDialog();
QIcon playIcon;
QIcon pauseIcon;
@@ -131,11 +163,12 @@ private:
Phonon::Effect *nextEffect;
QDialog *settingsDialog;
Ui_settings *ui;
-
+ QAction *m_fullScreenAction;
+
QWidget m_videoWindow;
Phonon::MediaObject m_MediaObject;
Phonon::AudioOutput m_AudioOutput;
- Phonon::VideoWidget *m_videoWidget;
+ MediaVideoWidget *m_videoWidget;
Phonon::Path m_audioOutputPath;
const bool m_hasSmallScreen;
};
diff --git a/demos/qmediaplayer/settings.ui b/demos/qmediaplayer/settings.ui
index d2cedd4..03bd70e 100644
--- a/demos/qmediaplayer/settings.ui
+++ b/demos/qmediaplayer/settings.ui
@@ -1,283 +1,314 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>settings</class>
- <widget class="QDialog" name="settings" >
- <property name="geometry" >
+ <widget class="QDialog" name="settings">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>360</width>
- <height>362</height>
+ <width>175</width>
+ <height>397</height>
</rect>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Settings</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QGroupBox" name="groupBox" >
- <property name="title" >
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
<string>Video options:</string>
</property>
- <property name="flat" >
+ <property name="flat">
<bool>true</bool>
</property>
- <layout class="QGridLayout" name="gridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_9" >
- <property name="text" >
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="5" column="2">
+ <widget class="QComboBox" name="scalemodeCombo">
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContentsOnFirstShow</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>Fit in view</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Scale and crop</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
<string>Contrast:</string>
</property>
</widget>
</item>
- <item row="0" column="1" colspan="2" >
- <widget class="QSlider" name="contrastSlider" >
- <property name="minimum" >
+ <item row="0" column="1" colspan="2">
+ <widget class="QSlider" name="contrastSlider">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="minimum">
<number>-8</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>8</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="tickPosition" >
+ <property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
- <property name="tickInterval" >
+ <property name="tickInterval">
<number>4</number>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_8" >
- <property name="text" >
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
<string>Brightness:</string>
</property>
</widget>
</item>
- <item row="1" column="1" colspan="2" >
- <widget class="QSlider" name="brightnessSlider" >
- <property name="minimum" >
+ <item row="1" column="1" colspan="2">
+ <widget class="QSlider" name="brightnessSlider">
+ <property name="minimum">
<number>-8</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>8</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="tickPosition" >
+ <property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
- <property name="tickInterval" >
+ <property name="tickInterval">
<number>4</number>
</property>
</widget>
</item>
- <item row="2" column="0" >
- <widget class="QLabel" name="label_7" >
- <property name="text" >
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
<string>Saturation:</string>
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2" >
- <widget class="QSlider" name="saturationSlider" >
- <property name="minimum" >
+ <item row="2" column="1" colspan="2">
+ <widget class="QSlider" name="saturationSlider">
+ <property name="minimum">
<number>-8</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>8</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="tickPosition" >
+ <property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
- <property name="tickInterval" >
+ <property name="tickInterval">
<number>4</number>
</property>
</widget>
</item>
- <item row="3" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
<string>Hue:</string>
</property>
</widget>
</item>
- <item row="3" column="1" colspan="2" >
- <widget class="QSlider" name="hueSlider" >
- <property name="minimum" >
+ <item row="3" column="1" colspan="2">
+ <widget class="QSlider" name="hueSlider">
+ <property name="minimum">
<number>-8</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>8</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="tickPosition" >
+ <property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
- <property name="tickInterval" >
+ <property name="tickInterval">
<number>4</number>
</property>
</widget>
</item>
- <item row="4" column="0" colspan="2" >
- <widget class="QLabel" name="label_10" >
- <property name="text" >
+ <item row="4" column="0" colspan="2">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
<string>Aspect ratio:</string>
</property>
</widget>
</item>
- <item row="4" column="2" >
- <widget class="QComboBox" name="aspectCombo" >
- <property name="minimumSize" >
- <size>
- <width>180</width>
- <height>0</height>
- </size>
+ <item row="4" column="2">
+ <widget class="QComboBox" name="aspectCombo">
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContentsOnFirstShow</enum>
</property>
<item>
- <property name="text" >
+ <property name="text">
<string>Auto</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>Stretch</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>4/3</string>
</property>
</item>
<item>
- <property name="text" >
+ <property name="text">
<string>16/9</string>
</property>
</item>
</widget>
</item>
- <item row="5" column="0" colspan="2" >
- <widget class="QLabel" name="label_11" >
- <property name="text" >
+ <item row="5" column="0" colspan="2">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
<string>Scale Mode:</string>
</property>
</widget>
</item>
- <item row="5" column="2" >
- <widget class="QComboBox" name="scalemodeCombo" >
- <property name="minimumSize" >
- <size>
- <width>180</width>
- <height>0</height>
- </size>
- </property>
- <item>
- <property name="text" >
- <string>Fit in view</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Scale and crop</string>
- </property>
- </item>
- </widget>
- </item>
</layout>
+ <zorder>scalemodeCombo</zorder>
+ <zorder>label_9</zorder>
+ <zorder>contrastSlider</zorder>
+ <zorder>label_8</zorder>
+ <zorder>brightnessSlider</zorder>
+ <zorder>label_7</zorder>
+ <zorder>saturationSlider</zorder>
+ <zorder>label_2</zorder>
+ <zorder>hueSlider</zorder>
+ <zorder>label_10</zorder>
+ <zorder>aspectCombo</zorder>
+ <zorder>label_11</zorder>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="groupBox_2" >
- <property name="title" >
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
<string>Audio options:</string>
</property>
- <property name="flat" >
+ <property name="flat">
<bool>true</bool>
</property>
- <layout class="QVBoxLayout" name="verticalLayout" >
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <layout class="QHBoxLayout" >
+ <layout class="QHBoxLayout">
<item>
- <widget class="QLabel" name="label" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimumSize" >
+ <property name="minimumSize">
<size>
- <width>90</width>
+ <width>10</width>
<height>0</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>Audio device:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
- <widget class="QComboBox" name="deviceCombo" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <widget class="QComboBox" name="deviceCombo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLength</enum>
+ </property>
</widget>
</item>
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" >
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QLabel" name="label_6" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimumSize" >
+ <property name="minimumSize">
<size>
- <width>90</width>
+ <width>10</width>
<height>0</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>Audio effect:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
- <widget class="QComboBox" name="audioEffectsCombo" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Maximum" hsizetype="Minimum" >
+ <widget class="QComboBox" name="audioEffectsCombo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLength</enum>
+ </property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="effectButton" >
- <property name="enabled" >
+ <widget class="QToolButton" name="effectButton">
+ <property name="enabled">
<bool>false</bool>
</property>
- <property name="text" >
+ <property name="text">
<string>Setup</string>
</property>
</widget>
@@ -285,123 +316,123 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" >
+ <layout class="QHBoxLayout">
<item>
- <widget class="QLabel" name="crossFadeLabel" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <widget class="QLabel" name="crossFadeLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimumSize" >
+ <property name="minimumSize">
<size>
- <width>90</width>
+ <width>10</width>
<height>0</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>Cross fade:</string>
</property>
- <property name="alignment" >
+ <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
- <layout class="QVBoxLayout" >
+ <layout class="QVBoxLayout">
<item>
- <widget class="QSlider" name="crossFadeSlider" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <widget class="QSlider" name="crossFadeSlider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimum" >
+ <property name="minimum">
<number>-20</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>20</number>
</property>
- <property name="singleStep" >
+ <property name="singleStep">
<number>1</number>
</property>
- <property name="pageStep" >
+ <property name="pageStep">
<number>2</number>
</property>
- <property name="value" >
+ <property name="value">
<number>0</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="tickPosition" >
+ <property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" >
+ <layout class="QHBoxLayout">
<item>
- <widget class="QLabel" name="crossFadeLabel1" >
- <property name="font" >
+ <widget class="QLabel" name="crossFadeLabel1">
+ <property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
- <property name="text" >
+ <property name="text">
<string>-10 Sec</string>
</property>
</widget>
</item>
<item>
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
- <width>40</width>
+ <width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QLabel" name="crossFadeLabel2" >
- <property name="font" >
+ <widget class="QLabel" name="crossFadeLabel2">
+ <property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
- <property name="text" >
+ <property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" stdset="0" >
+ <property name="sizeHint" stdset="0">
<size>
- <width>40</width>
+ <width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QLabel" name="crossFadeLabel3" >
- <property name="font" >
+ <widget class="QLabel" name="crossFadeLabel3">
+ <property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
- <property name="text" >
- <string>10 Sec</string>
+ <property name="text">
+ <string>10 Sec </string>
</property>
</widget>
</item>
@@ -415,11 +446,11 @@
</widget>
</item>
<item>
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="standardButtons" >
+ <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
@@ -434,11 +465,11 @@
<receiver>settings</receiver>
<slot>accept()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@@ -450,11 +481,11 @@
<receiver>settings</receiver>
<slot>reject()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
index 2059fbe..b6f53ae 100644
--- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
+++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
@@ -50,6 +50,8 @@ MMF::VideoPlayer::VideoPlayer()
, m_window(0)
, m_totalTime(0)
, m_pendingChanges(false)
+ , m_dsaActive(false)
+ , m_dsaWasActive(false)
{
construct();
}
@@ -61,6 +63,7 @@ MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player)
, m_window(0)
, m_totalTime(0)
, m_pendingChanges(false)
+ , m_dsaActive(false)
{
construct();
}
@@ -86,6 +89,9 @@ void MMF::VideoPlayer::construct()
))
);
+ // CVideoPlayerUtility::NewL starts DSA
+ m_dsaActive = true;
+
if (KErrNone != err)
changeState(ErrorState);
@@ -315,8 +321,7 @@ void MMF::VideoPlayer::getVideoWindow()
m_videoOutput->dump();
initVideoOutput();
- m_window = m_videoOutput->videoWindow();
- updateVideoRect();
+ videoWindowChanged();
} else
// Top-level window
m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
@@ -349,6 +354,18 @@ void MMF::VideoPlayer::initVideoOutput()
Q_ASSERT(connected);
connected = connect(
+ m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
+ this, SLOT(suspendDirectScreenAccess())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
+ m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
+ this, SLOT(resumeDirectScreenAccess())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
m_videoOutput, SIGNAL(aspectRatioChanged()),
this, SLOT(aspectRatioChanged())
);
@@ -370,12 +387,48 @@ void MMF::VideoPlayer::videoWindowChanged()
TRACE_ENTRY("state %d", state());
m_window = m_videoOutput->videoWindow();
-
updateVideoRect();
TRACE_EXIT_0();
}
+void MMF::VideoPlayer::suspendDirectScreenAccess()
+{
+ m_dsaWasActive = stopDirectScreenAccess();
+}
+
+void MMF::VideoPlayer::resumeDirectScreenAccess()
+{
+ if(m_dsaWasActive) {
+ startDirectScreenAccess();
+ m_dsaWasActive = false;
+ }
+}
+
+void MMF::VideoPlayer::startDirectScreenAccess()
+{
+ if(!m_dsaActive) {
+ TRAPD(err, m_player->StartDirectScreenAccessL());
+ if(KErrNone == err)
+ m_dsaActive = true;
+ else
+ setError(NormalError);
+ }
+}
+
+bool MMF::VideoPlayer::stopDirectScreenAccess()
+{
+ const bool dsaWasActive = m_dsaActive;
+ if(m_dsaActive) {
+ TRAPD(err, m_player->StopDirectScreenAccessL());
+ if(KErrNone == err)
+ m_dsaActive = false;
+ else
+ setError(NormalError);
+ }
+ return dsaWasActive;
+}
+
// Helper function for aspect ratio / scale mode handling
QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight)
{
@@ -393,7 +446,18 @@ QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight)
void MMF::VideoPlayer::updateVideoRect()
{
QRect videoRect;
- const QRect windowRect = m_videoOutput->videoWindowRect();
+ QRect windowRect = m_videoOutput->videoWindowRect();
+
+ // Clip to physical window size
+ // This is due to a defect in the layout when running on S60 3.2, which
+ // results in the rectangle of the video widget extending outside the
+ // screen in certain circumstances. These include the initial startup
+ // of the mediaplayer demo in portrait mode. When this rectangle is
+ // passed to the CVideoPlayerUtility, no video is rendered.
+ const TSize screenSize = m_screenDevice.SizeInPixels();
+ const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
+ windowRect = windowRect.intersected(screenRect);
+
const QSize windowSize = windowRect.size();
// Calculate size of smallest rect which contains video frame size
@@ -553,6 +617,7 @@ void MMF::VideoPlayer::applyVideoWindowChange()
TRACE("SetDisplayWindowL err %d", err);
setError(NormalError);
} else {
+ m_dsaActive = true;
TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias));
if(KErrNone != err) {
TRACE("SetScaleFactorL (2) err %d", err);
diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h
index 599bb88..abb1da8 100644
--- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h
+++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h
@@ -72,6 +72,8 @@ public Q_SLOTS:
void videoWindowChanged();
void aspectRatioChanged();
void scaleModeChanged();
+ void suspendDirectScreenAccess();
+ void resumeDirectScreenAccess();
private:
void construct();
@@ -89,6 +91,9 @@ private:
void applyPendingChanges();
void applyVideoWindowChange();
+ void startDirectScreenAccess();
+ bool stopDirectScreenAccess();
+
// AbstractMediaPlayer
virtual int numberOfMetaDataEntries() const;
virtual QPair<QString, QString> metaDataEntry(int index) const;
@@ -111,6 +116,8 @@ private:
qint64 m_totalTime;
bool m_pendingChanges;
+ bool m_dsaActive;
+ bool m_dsaWasActive;
};
diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
index 2efebdb..edad537 100644
--- a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
+++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
@@ -46,7 +46,7 @@ QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object)
stream << "widget (Symbian): ";
stream << "activated " << extra->activated << ' ';
- stream << "disableBlit " << extra->disableBlit << ' ';
+ stream << "nativePaintMode " << extra->nativePaintMode << ' ';
stream.flush();
result.append(array);
diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp
index ddf30de..119dcb1 100644
--- a/src/3rdparty/phonon/mmf/videooutput.cpp
+++ b/src/3rdparty/phonon/mmf/videooutput.cpp
@@ -34,6 +34,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <coecntrl.h>
+#include <coemain.h> // for CCoeEnv
+
QT_BEGIN_NAMESPACE
using namespace Phonon;
@@ -72,12 +74,8 @@ MMF::VideoOutput::VideoOutput
setAttribute(Qt::WA_NoSystemBackground, true);
setAutoFillBackground(false);
- // Causes QSymbianControl::Draw not to BitBlt this widget's region of the
- // backing store. Since the backing store is (by default) a 16MU bitmap,
- // blitting it results in this widget's screen region in the final
- // framebuffer having opaque alpha values. This in turn causes the video
- // to be invisible when running on the target device.
- qt_widget_private(this)->extraData()->disableBlit = true;
+ qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
+ qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
getVideoWindowRect();
registerForAncestorMoved();
@@ -288,5 +286,18 @@ void MMF::VideoOutput::dump() const
#endif
}
+void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/)
+{
+ emit beginVideoWindowNativePaint();
+}
+
+void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/)
+{
+ // Ensure that draw ops are executed into the WSERV output framebuffer
+ CCoeEnv::Static()->WsSession().Flush();
+
+ emit endVideoWindowNativePaint();
+}
+
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h
index 6dfe69d..2788401 100644
--- a/src/3rdparty/phonon/mmf/videooutput.h
+++ b/src/3rdparty/phonon/mmf/videooutput.h
@@ -63,10 +63,16 @@ public:
// Debugging output
void dump() const;
+public Q_SLOTS:
+ void beginNativePaintEvent(const QRect& /*controlRect*/);
+ void endNativePaintEvent(const QRect& /*controlRect*/);
+
Q_SIGNALS:
void videoWindowChanged();
void aspectRatioChanged();
void scaleModeChanged();
+ void beginVideoWindowNativePaint();
+ void endVideoWindowNativePaint();
protected:
// Override QWidget functions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 89d961c..ab57c32 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -823,6 +823,12 @@ void QSymbianControl::Draw(const TRect& controlRect) const
if (!engine)
return;
+ const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
+ if (sendNativePaintEvents) {
+ const QRect r = qt_TRect2QRect(controlRect);
+ QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
+ }
+
// Map source rectangle into coordinates of the backing store.
const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY);
const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase);
@@ -833,14 +839,48 @@ void QSymbianControl::Draw(const TRect& controlRect) const
CFbsBitmap *bitmap = s60Surface->symbianBitmap();
CWindowGc &gc = SystemGc();
- if(!qwidget->d_func()->extraData()->disableBlit) {
+ switch(qwidget->d_func()->extraData()->nativePaintMode) {
+ case QWExtra::Disable:
+ // Do nothing
+ break;
+
+ case QWExtra::Blit:
if (qwidget->d_func()->isOpaque)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
+ break;
+
+ case QWExtra::ZeroFill:
+ if (Window().DisplayMode() == EColor16MA) {
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+ gc.SetBrushColor(TRgb::Color16MA(0));
+ gc.Clear(controlRect);
+ } else {
+ gc.SetBrushColor(TRgb(0x000000));
+ gc.Clear(controlRect);
+ };
+ break;
+
+ default:
+ Q_ASSERT(false);
}
} else {
surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
}
+
+ if (sendNativePaintEvents) {
+ const QRect r = qt_TRect2QRect(controlRect);
+ // The draw ops aren't actually sent to WSERV until the graphics
+ // context is deactivated, which happens in the function calling
+ // this one. We therefore delay the delivery of endNativePaintEvent,
+ // to ensure that drawing has completed by the time the widget
+ // receives the event. Note that, if the widget needs to ensure
+ // that the draw ops have actually been executed into the output
+ // framebuffer, a call to RWsSession::Flush is required in the
+ // endNativePaintEvent implementation.
+ QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r));
+ }
}
void QSymbianControl::SizeChanged()
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 66efcb5..04cf4bb 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -230,12 +230,42 @@ struct QWExtra {
#elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian
uint activated : 1; // RWindowBase::Activated has been called
- // If set, QSymbianControl::Draw does not blit this widget
- // This is to allow, for use cases such as video, widgets which, from the Qt point
- // of view, are just placeholders in the scene. For these widgets, any necessary
- // drawing to the UI framebuffer is done by the relevant Symbian subsystem. For
- // video rendering, this would be an MMF controller, or MDF post-processor.
- uint disableBlit : 1;
+ /**
+ * Defines the behaviour of QSymbianControl::Draw.
+ */
+ enum NativePaintMode {
+ /**
+ * Normal drawing mode: blits the required region of the backing store
+ * via WSERV.
+ */
+ Blit,
+
+ /**
+ * Disable drawing for this widget.
+ */
+ Disable,
+
+ /**
+ * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows
+ * with an EColor16MU display mode, zero is written only into the R, G and B
+ * channels of the pixel.
+ */
+ ZeroFill,
+
+ Default = Blit
+ };
+
+ NativePaintMode nativePaintMode : 2;
+
+ /**
+ * If this bit is set, each native widget receives the signals from the
+ * Symbian control immediately before and immediately after draw ops are
+ * sent to the window server for this control:
+ * void beginNativePaintEvent(const QRect &paintRect);
+ * void endNativePaintEvent(const QRect &paintRect);
+ */
+ uint receiveNativePaintEvents : 1;
+
#endif
};
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 359df2a..37614c7 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -881,7 +881,8 @@ void QWidgetPrivate::deleteTLSysExtra()
void QWidgetPrivate::createSysExtra()
{
extra->activated = 0;
- extra->disableBlit = 0;
+ extra->nativePaintMode = QWExtra::Default;
+ extra->receiveNativePaintEvents = 0;
}
void QWidgetPrivate::deleteSysExtra()
diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro
index 2d9c489..37adfa9 100644
--- a/src/s60installs/s60installs.pro
+++ b/src/s60installs/s60installs.pro
@@ -90,7 +90,7 @@ symbian: {
}
contains(QT_CONFIG, phonon): {
- qtlibraries.sources += Phonon.dll
+ qtlibraries.sources += phonon.dll
}
contains(QT_CONFIG, script): {