diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/phonon/mmf/ancestormovemonitor.cpp | 175 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/ancestormovemonitor.h | 95 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/backend.cpp | 7 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/backend.h | 7 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/videooutput.cpp | 30 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/videooutput.h | 15 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/videowidget.cpp | 5 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/videowidget.h | 3 | ||||
-rw-r--r-- | src/plugins/phonon/mmf/plugin/plugin.pro | 2 |
9 files changed, 328 insertions, 11 deletions
diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp new file mode 100644 index 0000000..876499c --- /dev/null +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp @@ -0,0 +1,175 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ancestormovemonitor.h" +#include "utils.h" +#include "videooutput.h" + +#include <QCoreApplication> + +QT_BEGIN_NAMESPACE + +using namespace Phonon::MMF; + +/*! \class MMF::AncestorMoveMonitor + \internal + \brief Class which installs a global event filter, and listens for move + events which may affect the absolute position of widgets registered with + the monitor + See QTBUG-4956 +*/ + +//----------------------------------------------------------------------------- +// Constructor / destructor +//----------------------------------------------------------------------------- + +AncestorMoveMonitor::AncestorMoveMonitor(QObject *parent) + : QObject(parent) +{ + QCoreApplication::instance()->installEventFilter(this); +} + +AncestorMoveMonitor::~AncestorMoveMonitor() +{ + QCoreApplication::instance()->removeEventFilter(this); +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +void AncestorMoveMonitor::registerTarget(VideoOutput *target) +{ + TRACE_CONTEXT(AncestorMoveMonitor::registerTarget, EVideoInternal); + TRACE_ENTRY("target 0x%08x", target); + + // First un-register the target, in case this is being called as a result + // of re-parenting. This is not the most efficient way to update the + // target hash, but since this is not likely to be a frequent operation, + // simplicity is preferred over outright speed. In any case, re-parenting + // of the video widget leads to re-creation of native windows, which is + // likely to take far more processing than any implementation of this + // function. + unRegisterTarget(target); + + QWidget *ancestor = target->parentWidget(); + while(ancestor) { + const Hash::iterator it = m_hash.find(ancestor); + if(m_hash.end() == it) { + TargetList targetList; + targetList.append(target); + m_hash.insert(ancestor, targetList); + } else { + TargetList& targetList = it.value(); + Q_ASSERT(targetList.indexOf(target) == -1); + targetList.append(target); + } + ancestor = ancestor->parentWidget(); + } + + dump(); + + TRACE_EXIT_0(); +} + +void AncestorMoveMonitor::unRegisterTarget(VideoOutput *target) +{ + TRACE_CONTEXT(AncestorMoveMonitor::unRegisterTarget, EVideoInternal); + TRACE_ENTRY("target 0x%08x", target); + + Hash::iterator it = m_hash.begin(); + while(it != m_hash.end()) { + TargetList& targetList = it.value(); + const int index = targetList.indexOf(target); + if(index != -1) + targetList.removeAt(index); + if(targetList.count()) + ++it; + else + it = m_hash.erase(it); + } + + dump(); + + TRACE_EXIT_0(); +} + +bool AncestorMoveMonitor::eventFilter(QObject *watched, QEvent *event) +{ + TRACE_CONTEXT(AncestorMoveMonitor::eventFilter, EVideoInternal); + + if(event->type() == QEvent::Move || event->type() == QEvent::ParentChange) { + + TRACE_ENTRY("watched 0x%08x event.type %d", watched, event->type()); + + const Hash::const_iterator it = m_hash.find(watched); + if(it != m_hash.end()) { + const TargetList& targetList = it.value(); + VideoOutput* target = 0; + foreach(target, targetList) { + switch (event->type()) { + + case QEvent::Move: + // Notify the target that its ancestor has moved + target->ancestorMoved(); + break; + + case QEvent::ParentChange: + // Update ancestor list for the target + registerTarget(target); + break; + + default: + Q_ASSERT(false); + } + } + } + + TRACE_EXIT_0(); + } + + // The event is never consumed by this filter + return false; +} + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void AncestorMoveMonitor::dump() +{ +#ifndef QT_NO_DEBUG + TRACE_CONTEXT(AncestorMoveMonitor::dump, EVideoInternal); + for(Hash::const_iterator it = m_hash.begin(); + it != m_hash.end(); ++it) { + const QObject *ancestor = it.key(); + TRACE("ancestor 0x%08x", ancestor); + const TargetList& targetList = it.value(); + VideoOutput* target = 0; + foreach(target, targetList) { + TRACE(" target 0x%08x", target); + } + } +#endif +} + + + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.h b/src/3rdparty/phonon/mmf/ancestormovemonitor.h new file mode 100644 index 0000000..0e681aa --- /dev/null +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.h @@ -0,0 +1,95 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_ANCESTORMOVEMONITOR_H +#define PHONON_MMF_ANCESTORMOVEMONITOR_H + +#include <QObject> +#include <QHash> +#include <QList> + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ +class VideoOutput; + +class AncestorMoveMonitor : public QObject +{ + Q_OBJECT + +public: + explicit AncestorMoveMonitor(QObject *parent); + ~AncestorMoveMonitor(); + + /** + * Register target widget for notification. + * + * The widget receives an ancestorMoveEvent callback when a move event + * is delivered to any of its ancestors: + * + * If the target is already registered, this function causes its + * ancestor list to be updated - therefore it should be called when + * the target receives a ParentChange event. + */ + void registerTarget(VideoOutput *target); + + /** + * Remove target from the monitor. + * + * The target will no longer receive notification when move events are + * delivered to its ancestors. + */ + void unRegisterTarget(VideoOutput *target); + +protected: + /** + * Function which receives events from the global event filter. + */ + bool eventFilter(QObject *watched, QEvent *event); + + void dump(); + +private: + /** + * List of registered target widgets which descend from a given + * ancestor. + * + * Note that the members of the list should be non-redundant; this + * invariant is checked in debug builds. Semantically, the value is + * therefore a set, however we use QList rather than QSet for + * efficiency of iteration. + */ + typedef QList<VideoOutput *> TargetList; + + /** + * Map from widget on which the move event occurs, to widgets which + * descend from it and therefore need to be notified. + */ + typedef QHash<QObject *, TargetList> Hash; + Hash m_hash; + +}; +} +} + +QT_END_NAMESPACE + +#endif diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index f542ec9..cac27e3 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -24,6 +24,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <apmstd.h> // for TDataType #include "abstractaudioeffect.h" +#include "ancestormovemonitor.h" #include "audiooutput.h" #include "audioplayer.h" #include "backend.h" @@ -45,7 +46,9 @@ using namespace Phonon::MMF; \internal */ -Backend::Backend(QObject *parent) : QObject(parent) +Backend::Backend(QObject *parent) + : QObject(parent) + , m_ancestorMoveMonitor(new AncestorMoveMonitor(this)) { TRACE_CONTEXT(Backend::Backend, EBackend); TRACE_ENTRY_0(); @@ -87,7 +90,7 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const return EffectFactory::createAudioEffect(effect, parent); } case VideoWidgetClass: - result = new VideoWidget(qobject_cast<QWidget *>(parent)); + result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast<QWidget *>(parent)); break; default: diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 1886ae6..9e3d3b3 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -19,8 +19,11 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_BACKEND_H #define PHONON_MMF_BACKEND_H +#include "ancestormovemonitor.h" + #include <Phonon/MediaSource> #include <Phonon/BackendInterface> +#include <QScopedPointer> QT_BEGIN_NAMESPACE @@ -47,6 +50,10 @@ public: Q_SIGNALS: void objectDescriptionChanged(ObjectDescriptionType); + +private: + QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor; + }; } } diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index f0393a7..5288b4d 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include "ancestormovemonitor.h" #include "utils.h" #include "videooutput.h" #include "videooutputobserver.h" @@ -44,8 +45,10 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoOutput::VideoOutput(QWidget* parent) +MMF::VideoOutput::VideoOutput + (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) : QWidget(parent) + , m_ancestorMoveMonitor(ancestorMoveMonitor) , m_observer(0) { TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal); @@ -63,6 +66,8 @@ MMF::VideoOutput::VideoOutput(QWidget* parent) // to be invisible when running on the target device. qt_widget_private(this)->extraData()->disableBlit = true; + registerForAncestorMoved(); + dump(); TRACE_EXIT_0(); @@ -73,6 +78,8 @@ MMF::VideoOutput::~VideoOutput() TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal); TRACE_ENTRY_0(); + m_ancestorMoveMonitor->unRegisterTarget(this); + TRACE_EXIT_0(); } @@ -97,6 +104,15 @@ void MMF::VideoOutput::setObserver(VideoOutputObserver* observer) m_observer = observer; } +void MMF::VideoOutput::ancestorMoved() +{ + TRACE_CONTEXT(VideoOutput::ancestorMoved, EVideoInternal); + TRACE_ENTRY_0(); + + videoOutputRegionChanged(); + + TRACE_EXIT_0(); +} //----------------------------------------------------------------------------- // QWidget @@ -154,8 +170,11 @@ bool MMF::VideoOutput::event(QEvent* event) TRACE_0("WinIdChange"); videoOutputRegionChanged(); return true; - } - else + } else if (event->type() == QEvent::ParentChange) { + // Tell ancestor move monitor to update ancestor list for this widget + registerForAncestorMoved(); + return true; + } else return QWidget::event(event); } @@ -171,6 +190,11 @@ void MMF::VideoOutput::videoOutputRegionChanged() m_observer->videoOutputRegionChanged(); } +void MMF::VideoOutput::registerForAncestorMoved() +{ + m_ancestorMoveMonitor->registerTarget(this); +} + void MMF::VideoOutput::dump() const { #ifndef QT_NO_DEBUG diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h index 7bc0b52..db4d127 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/videooutput.h @@ -30,6 +30,7 @@ namespace Phonon { namespace MMF { +class AncestorMoveMonitor; class VideoOutputObserver; class VideoOutput : public QWidget @@ -37,12 +38,14 @@ class VideoOutput : public QWidget Q_OBJECT public: - explicit VideoOutput(QWidget* parent); + VideoOutput(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); ~VideoOutput(); void setFrameSize(const QSize& size); void setObserver(VideoOutputObserver* observer); + void ancestorMoved(); + protected: // Override QWidget functions QSize sizeHint() const; @@ -55,11 +58,17 @@ private: void dump() const; void videoOutputRegionChanged(); + void registerForAncestorMoved(); + private: - QSize m_frameSize; + // Not owned + AncestorMoveMonitor* m_ancestorMoveMonitor; // Not owned - VideoOutputObserver* m_observer; + VideoOutputObserver* m_observer; + + QSize m_frameSize; + }; } } diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp index 8a5c9ff..7d7abf1 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -49,9 +49,10 @@ static const qreal DefaultSaturation = 1.0; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoWidget::VideoWidget(QWidget* parent) +MMF::VideoWidget::VideoWidget + (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) : MediaNode(parent) - , m_widget(new VideoOutput(parent)) + , m_widget(new VideoOutput(ancestorMoveMonitor, parent)) , m_aspectRatio(DefaultAspectRatio) , m_brightness(DefaultBrightness) , m_scaleMode(DefaultScaleMode) diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index 970f749..318dfae 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -31,6 +31,7 @@ namespace Phonon { namespace MMF { +class AncestorMoveMonitor; class VideoOutput; class VideoWidget : public MediaNode @@ -40,7 +41,7 @@ class VideoWidget : public MediaNode Q_INTERFACES(Phonon::VideoWidgetInterface) public: - VideoWidget(QWidget* parent); + VideoWidget(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); ~VideoWidget(); // VideoWidgetInterface diff --git a/src/plugins/phonon/mmf/plugin/plugin.pro b/src/plugins/phonon/mmf/plugin/plugin.pro index eb7fd27..793c307 100644 --- a/src/plugins/phonon/mmf/plugin/plugin.pro +++ b/src/plugins/phonon/mmf/plugin/plugin.pro @@ -26,6 +26,7 @@ HEADERS += \ $$PHONON_MMF_DIR/abstractaudioeffect.h \ $$PHONON_MMF_DIR/abstractmediaplayer.h \ $$PHONON_MMF_DIR/abstractplayer.h \ + $$PHONON_MMF_DIR/ancestormovemonitor.h \ $$PHONON_MMF_DIR/audiooutput.h \ $$PHONON_MMF_DIR/audioequalizer.h \ $$PHONON_MMF_DIR/audioplayer.h \ @@ -47,6 +48,7 @@ SOURCES += \ $$PHONON_MMF_DIR/abstractaudioeffect.cpp \ $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ $$PHONON_MMF_DIR/abstractplayer.cpp \ + $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ $$PHONON_MMF_DIR/audiooutput.cpp \ $$PHONON_MMF_DIR/audioequalizer.cpp \ $$PHONON_MMF_DIR/audioplayer.cpp \ |