summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGareth Stockwell <gareth.stockwell@sosco.com>2009-09-07 10:26:02 (GMT)
committerGareth Stockwell <gareth.stockwell@sosco.com>2009-09-07 10:26:02 (GMT)
commit386800053d03f3f42bc5d0e0809059b534bac5d4 (patch)
tree0b31c0d6d55d52892dce7861449f57d3ce32fe4a /src
parent65c8d29d8bad265a236431ab57b03f7b2614c53a (diff)
downloadQt-386800053d03f3f42bc5d0e0809059b534bac5d4.zip
Qt-386800053d03f3f42bc5d0e0809059b534bac5d4.tar.gz
Qt-386800053d03f3f42bc5d0e0809059b534bac5d4.tar.bz2
Added visitor-based object tree dumping framework, which dumps details of Symbian control / window associated with each widget
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/phonon/mmf/defs.h2
-rw-r--r--src/3rdparty/phonon/mmf/objectdump.cpp527
-rw-r--r--src/3rdparty/phonon/mmf/objectdump.h164
-rw-r--r--src/3rdparty/phonon/mmf/objectdump_symbian.cpp129
-rw-r--r--src/3rdparty/phonon/mmf/objectdump_symbian.h56
-rw-r--r--src/3rdparty/phonon/mmf/objecttree.cpp102
-rw-r--r--src/3rdparty/phonon/mmf/objecttree.h115
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.cpp73
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.h8
-rw-r--r--src/3rdparty/phonon/mmf/videoplayer.cpp24
-rw-r--r--src/plugins/phonon/mmf/mmf.pro15
11 files changed, 1154 insertions, 61 deletions
diff --git a/src/3rdparty/phonon/mmf/defs.h b/src/3rdparty/phonon/mmf/defs.h
index 674e767..60f363b 100644
--- a/src/3rdparty/phonon/mmf/defs.h
+++ b/src/3rdparty/phonon/mmf/defs.h
@@ -34,8 +34,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
// rect, i.e. QWidget::winId()->Rect()
//#define PHONON_MMF_HARD_CODE_VIDEO_RECT
-#define PHONON_MMF_DEBUG_VIDEO_OUTPUT
-
QT_BEGIN_NAMESPACE
namespace Phonon
diff --git a/src/3rdparty/phonon/mmf/objectdump.cpp b/src/3rdparty/phonon/mmf/objectdump.cpp
new file mode 100644
index 0000000..50c6bf8
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump.cpp
@@ -0,0 +1,527 @@
+/* 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 <QByteArray>
+#include <QDebug>
+#include <QHash>
+#include <QTextStream>
+#include <QWidget>
+
+#include "objectdump.h"
+#include "objecttree.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+
+//-----------------------------------------------------------------------------
+// QObjectAnnotator
+//-----------------------------------------------------------------------------
+
+QAnnotator::~QAnnotator()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Annotators
+//-----------------------------------------------------------------------------
+
+QList<QByteArray> QAnnotatorBasic::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << '[' << &object << ']';
+ stream << ' ';
+ stream << object.metaObject()->className();
+
+ if(object.objectName() != "")
+ stream << " \"" << object.objectName() << '"';
+
+ if(object.isWidgetType())
+ stream << " isWidget";
+
+ stream.flush();
+ result.append(array);
+ return result;
+}
+
+QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if(widget) {
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "widget: ";
+
+ if(widget->isVisible())
+ stream << "visible ";
+ else
+ stream << "invisible ";
+
+ stream << widget->x() << ',' << widget->y() << ' ';
+ stream << widget->size().width() << 'x'<< widget->size().height() << ' ';
+
+ stream << "hint " << widget->sizeHint().width() << 'x' << widget->sizeHint().height();
+
+ stream.flush();
+ result.append(array);
+ }
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// Base class for QDumperPrivate, QVisitorPrivate
+//-----------------------------------------------------------------------------
+
+class QDumperBase
+{
+public:
+ QDumperBase();
+ ~QDumperBase();
+
+ void setPrefix(const QString& prefix);
+ void addAnnotator(QAnnotator* annotator);
+
+protected:
+ QByteArray m_prefix;
+ QList<QAnnotator*> m_annotators;
+
+};
+
+QDumperBase::QDumperBase()
+{
+
+}
+
+QDumperBase::~QDumperBase()
+{
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators)
+ delete annotator;
+}
+
+void QDumperBase::setPrefix(const QString& prefix)
+{
+ m_prefix = prefix.count()
+ ? (prefix + " ").toAscii()
+ : prefix.toAscii();
+}
+
+void QDumperBase::addAnnotator(QAnnotator* annotator)
+{
+ // Protect against an exception occurring during QList::append
+ QScopedPointer<QAnnotator> holder(annotator);
+ m_annotators.append(annotator);
+ holder.take();
+}
+
+
+//-----------------------------------------------------------------------------
+// QDumper
+//-----------------------------------------------------------------------------
+
+class QDumperPrivate : public QDumperBase
+{
+public:
+ QDumperPrivate();
+ ~QDumperPrivate();
+
+ void dumpObject(const QObject& object);
+
+};
+
+
+QDumperPrivate::QDumperPrivate()
+{
+
+}
+
+QDumperPrivate::~QDumperPrivate()
+{
+
+}
+
+void QDumperPrivate::dumpObject(const QObject& object)
+{
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators) {
+
+ const QList<QByteArray> annotations = annotator->annotation(object);
+ QByteArray annotation;
+ foreach(annotation, annotations) {
+ QByteArray buffer(m_prefix);
+ buffer.append(annotation);
+ qDebug() << buffer.constData();
+ }
+ }
+}
+
+
+QDumper::QDumper()
+ : d_ptr(new QDumperPrivate)
+{
+
+}
+
+QDumper::~QDumper()
+{
+
+}
+
+void QDumper::setPrefix(const QString& prefix)
+{
+ d_func()->setPrefix(prefix);
+}
+
+void QDumper::addAnnotator(QAnnotator* annotator)
+{
+ d_func()->addAnnotator(annotator);
+}
+
+void QDumper::dumpObject(const QObject& object)
+{
+ d_func()->dumpObject(object);
+}
+
+
+//-----------------------------------------------------------------------------
+// QVisitor
+//-----------------------------------------------------------------------------
+
+class QVisitorPrivate : public QDumperBase
+{
+public:
+ QVisitorPrivate();
+ ~QVisitorPrivate();
+
+ void setIndent(unsigned indent);
+
+ void visitNode(const QObject& object);
+ void visitComplete();
+
+private:
+ class Node
+ {
+ public:
+ Node();
+ ~Node();
+
+ QList<QByteArray> m_annotation;
+ QList<Node*> m_children;
+
+ typedef QList<Node*>::const_iterator child_iterator;
+ };
+
+private:
+ Node* findNode(const QObject* object) const;
+ QByteArray branchBuffer(const QList<bool>& branches, bool isNodeLine, bool isLastChild) const;
+ void dumpRecursive(const Node& node, QList<bool> branches, bool isLastChild);
+ void dumpNode(const Node& node, const QList<bool>& branches, bool isLastChild);
+
+private:
+ unsigned m_indent;
+
+ QScopedPointer<Node> m_root;
+
+ // Hash table used to associate internal nodes with QObjects
+ typedef QHash<const QObject*, Node*> Hash;
+ Hash m_hash;
+};
+
+static const unsigned DefaultIndent = 2;
+
+QVisitorPrivate::QVisitorPrivate()
+ : m_indent(DefaultIndent)
+{
+
+}
+
+QVisitorPrivate::~QVisitorPrivate()
+{
+
+}
+
+void QVisitorPrivate::setIndent(unsigned indent)
+{
+ m_indent = indent;
+}
+
+// Builds up a mirror of the object tree, rooted in m_root, with each node
+// storing annotations generated by
+void QVisitorPrivate::visitNode(const QObject& object)
+{
+ QObject* const objectParent = object.parent();
+ Node* const nodeParent = objectParent ? findNode(objectParent) : NULL;
+
+ // Create a new node and store in scoped pointer for exception safety
+ Node* node = new Node;
+ QScopedPointer<Node> nodePtr(node);
+
+ // Associate node with QObject
+ m_hash.insert(&object, node);
+
+ // Insert node into internal tree
+ if(nodeParent)
+ {
+ nodeParent->m_children.append(nodePtr.take());
+ }
+ else
+ {
+ Q_ASSERT(m_root.isNull());
+ m_root.reset(nodePtr.take());
+ }
+
+ // Generate and store annotations
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators)
+ node->m_annotation.append( annotator->annotation(object) );
+}
+
+void QVisitorPrivate::visitComplete()
+{
+ QList<bool> branches;
+ static const bool isLastChild = true;
+ dumpRecursive(*m_root, branches, isLastChild);
+ m_root.reset(NULL);
+}
+
+QVisitorPrivate::Node* QVisitorPrivate::findNode(const QObject* object) const
+{
+ Hash::const_iterator i = m_hash.find(object);
+ return (m_hash.end() == i) ? NULL : *i;
+}
+
+QByteArray QVisitorPrivate::branchBuffer
+ (const QList<bool>& branches, bool isNodeLine, bool isLastChild) const
+{
+ const int depth = branches.count();
+
+ const QByteArray indent(m_indent, ' ');
+ const QByteArray horiz(m_indent, '-');
+
+ QByteArray buffer;
+ QTextStream stream(&buffer);
+
+ for (int i=0; i<depth-1; ++i) {
+ if(branches[i])
+ stream << '|';
+ else
+ stream << ' ';
+ stream << indent;
+ }
+
+ if(depth) {
+ if(isNodeLine)
+ stream << '+' << horiz;
+ else {
+ if(!isLastChild)
+ stream << '|';
+ else
+ stream << ' ';
+ stream << indent;
+ }
+ }
+
+ stream.flush();
+ buffer.push_front(m_prefix);
+
+ return buffer;
+}
+
+void QVisitorPrivate::dumpRecursive
+ (const Node& node, QList<bool> branches, bool isLastChild)
+{
+ dumpNode(node, branches, isLastChild);
+
+ // Recurse down tree
+ const Node::child_iterator begin = node.m_children.begin();
+ const Node::child_iterator end = node.m_children.end();
+ for(Node::child_iterator i = begin; end != i; ++i) {
+
+ isLastChild = (end == i + 1);
+
+ if(begin == i)
+ branches.push_back(!isLastChild);
+ else
+ branches.back() = !isLastChild;
+
+ static const bool isNodeLine = false;
+ const QByteArray buffer = branchBuffer(branches, isNodeLine, false);
+ qDebug() << buffer.constData();
+
+ dumpRecursive(**i, branches, isLastChild);
+ }
+}
+
+void QVisitorPrivate::dumpNode
+ (const Node& node, const QList<bool>& branches, bool isLastChild)
+{
+ const QList<QByteArray>::const_iterator
+ begin = node.m_annotation.begin(), end = node.m_annotation.end();
+
+ if(begin == end) {
+ // No annotations - just dump the object pointer
+ const bool isNodeLine = true;
+ QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild);
+ qDebug() << NULL; // TODO
+ }
+ else {
+ // Dump annotations
+ for(QList<QByteArray>::const_iterator i = begin; end != i; ++i) {
+ const bool isNodeLine = (begin == i);
+ QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild);
+ buffer.append(*i);
+ qDebug() << buffer.constData();
+ }
+ }
+}
+
+
+// QVisitorPrivate::Node
+
+QVisitorPrivate::Node::Node()
+{
+
+}
+
+QVisitorPrivate::Node::~Node()
+{
+ Node* child;
+ foreach(child, m_children)
+ delete child;
+}
+
+
+// QVisitor
+
+QVisitor::QVisitor()
+ : d_ptr(new QVisitorPrivate)
+{
+
+}
+
+QVisitor::~QVisitor()
+{
+
+}
+
+void QVisitor::setPrefix(const QString& prefix)
+{
+ d_func()->setPrefix(prefix);
+}
+
+void QVisitor::setIndent(unsigned indent)
+{
+ d_func()->setIndent(indent);
+}
+
+void QVisitor::addAnnotator(QAnnotator* annotator)
+{
+ d_func()->addAnnotator(annotator);
+}
+
+void QVisitor::visitPrepare()
+{
+ // Do nothing
+}
+
+void QVisitor::visitNode(const QObject& object)
+{
+ d_func()->visitNode(object);
+}
+
+void QVisitor::visitComplete()
+{
+ d_func()->visitComplete();
+}
+
+
+//-----------------------------------------------------------------------------
+// Utility functions
+//-----------------------------------------------------------------------------
+
+void addDefaultAnnotators_sys(QDumper& visitor);
+void addDefaultAnnotators_sys(QVisitor& visitor);
+
+void addDefaultAnnotators(QDumper& dumper)
+{
+ dumper.addAnnotator(new QAnnotatorBasic);
+ dumper.addAnnotator(new QAnnotatorWidget);
+
+ // Add platform-specific annotators
+ addDefaultAnnotators_sys(dumper);
+}
+
+void addDefaultAnnotators(QVisitor& visitor)
+{
+ visitor.addAnnotator(new QAnnotatorBasic);
+ visitor.addAnnotator(new QAnnotatorWidget);
+
+ // Add platform-specific annotators
+ addDefaultAnnotators_sys(visitor);
+}
+
+void dumpTreeFromRoot(const QObject& root, QVisitor& visitor)
+{
+ // Set up iteration range
+ ObjectTree::DepthFirstConstIterator begin(root), end;
+
+ // Invoke generic visitor algorithm
+ ObjectTree::visit(begin, end, visitor);
+}
+
+void dumpTreeFromLeaf(const QObject& leaf, QVisitor& visitor)
+{
+ // Walk up to root
+ const QObject* root = &leaf;
+ while(root->parent())
+ {
+ root = root->parent();
+ }
+
+ dumpTreeFromRoot(*root, visitor);
+}
+
+void dumpAncestors(const QObject& leaf, QVisitor& visitor)
+{
+ // Set up iteration range
+ ObjectTree::AncestorConstIterator begin(leaf), end;
+
+ // Invoke generic visitor algorithm
+ ObjectTree::visit(begin, end, visitor);
+}
+
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+
+
diff --git a/src/3rdparty/phonon/mmf/objectdump.h b/src/3rdparty/phonon/mmf/objectdump.h
new file mode 100644
index 0000000..4efc015
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump.h
@@ -0,0 +1,164 @@
+/* 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 OBJECTDUMP_H
+#define OBJECTDUMP_H
+
+#include <QObject>
+#include <QList>
+#include <QByteArray>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+
+/**
+ * Abstract base for annotator classes invoked by QVisitor.
+ */
+class QAnnotator : public QObject
+{
+ Q_OBJECT
+public:
+ virtual ~QAnnotator();
+ virtual QList<QByteArray> annotation(const QObject& object) = 0;
+};
+
+/**
+ * Annotator which replicates QObject::dumpObjectTree functionality.
+ */
+class QAnnotatorBasic : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+/**
+ * Annotator which returns widget information.
+ */
+class QAnnotatorWidget : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+
+class QDumperPrivate;
+
+/**
+ * Class used to dump information about individual QObjects.
+ */
+class QDumper : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDumper)
+
+public:
+ QDumper();
+ ~QDumper();
+
+ /**
+ * Specify a prefix, to be printed on each line of output.
+ */
+ void setPrefix(const QString& prefix);
+
+ /**
+ * Takes ownership of annotator.
+ */
+ void addAnnotator(QAnnotator* annotator);
+
+ /**
+ * Invoke each annotator on the object and write to debug output.
+ */
+ void dumpObject(const QObject& object);
+
+private:
+ QScopedPointer<QDumperPrivate> d_ptr;
+
+};
+
+
+class QVisitorPrivate;
+
+/**
+ * Visitor class which dumps information about nodes in the object tree.
+ */
+class QVisitor : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QVisitor)
+
+public:
+ QVisitor();
+ ~QVisitor();
+
+ /**
+ * Specify a prefix, to be printed on each line of output.
+ */
+ void setPrefix(const QString& prefix);
+
+ /**
+ * Set number of spaces by which each level of the tree is indented.
+ */
+ void setIndent(unsigned indent);
+
+ /**
+ * Called by the visitor algorithm before starting the visit.
+ */
+ void visitPrepare();
+
+ /**
+ * Called by the visitor algorithm as each node is visited.
+ */
+ void visitNode(const QObject& object);
+
+ /**
+ * Called by the visitor algorithm when the visit is complete.
+ */
+ void visitComplete();
+
+ /**
+ * Takes ownership of annotator.
+ */
+ void addAnnotator(QAnnotator* annotator);
+
+private:
+ QScopedPointer<QVisitorPrivate> d_ptr;
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Utility functions
+//-----------------------------------------------------------------------------
+
+void addDefaultAnnotators(QDumper& dumper);
+void addDefaultAnnotators(QVisitor& visitor);
+
+void dumpTreeFromRoot(const QObject& root, QVisitor& visitor);
+void dumpTreeFromLeaf(const QObject& leaf, QVisitor& visitor);
+void dumpAncestors(const QObject& leaf, QVisitor& visitor);
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
new file mode 100644
index 0000000..54ebc55
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
@@ -0,0 +1,129 @@
+/* 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 <QTextStream>
+#include <QWidget>
+#include <coecntrl.h>
+#include "objectdump_symbian.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+namespace Symbian
+{
+
+QList<QByteArray> QAnnotatorControl::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if(widget) {
+
+ const CCoeControl* control = widget->effectiveWinId();
+ if(control) {
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "control: " << control << ' ';
+ stream << "parent " << control->Parent() << ' ';
+
+ if(control->IsVisible())
+ stream << "visible ";
+ else
+ stream << "invisible ";
+
+ stream << control->Position().iX << ',' << control->Position().iY << ' ';
+ stream << control->Size().iWidth << 'x' << control->Size().iHeight;
+
+ if(control->OwnsWindow())
+ stream << " ownsWindow ";
+
+ stream.flush();
+ result.append(array);
+ }
+ }
+
+ return result;
+}
+
+QList<QByteArray> QAnnotatorWindow::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if(widget) {
+
+ const CCoeControl* control = widget->effectiveWinId();
+ if(control) {
+
+ RDrawableWindow& window = *(control->DrawableWindow());
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "window: ";
+
+ // Client-side window handle
+ // Cast to a void pointer so that log output is in hexadecimal format.
+ stream << "cli " << reinterpret_cast<const void*>(window.ClientHandle()) << ' ';
+
+ // Server-side address of CWsWindow object
+ // This is useful for correlation with the window tree dumped by the window
+ // server (see RWsSession::LogCommand).
+ // Cast to a void pointer so that log output is in hexadecimal format.
+ stream << "srv " << reinterpret_cast<const void*>(window.WsHandle()) << ' ';
+
+ stream << "group " << window.WindowGroupId() << ' ';
+
+ // Client-side handle to the parent window.
+ // Cast to a void pointer so that log output is in hexadecimal format.
+ stream << "parent " << reinterpret_cast<const void*>(window.Parent()) << ' ';
+
+ stream << window.Position().iX << ',' << window.Position().iY << ' ';
+ stream << '(' << window.AbsPosition().iX << ',' << window.AbsPosition().iY << ") ";
+ stream << window.Size().iWidth << 'x' << window.Size().iHeight;
+
+ stream.flush();
+ result.append(array);
+ }
+ }
+
+ return result;
+}
+
+} // namespace Symbian
+
+void addDefaultAnnotators_sys(QDumper& dumper)
+{
+ dumper.addAnnotator(new Symbian::QAnnotatorControl);
+ dumper.addAnnotator(new Symbian::QAnnotatorWindow);
+}
+
+void addDefaultAnnotators_sys(QVisitor& visitor)
+{
+ visitor.addAnnotator(new Symbian::QAnnotatorControl);
+ visitor.addAnnotator(new Symbian::QAnnotatorWindow);
+}
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+
diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.h b/src/3rdparty/phonon/mmf/objectdump_symbian.h
new file mode 100644
index 0000000..26ab308
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump_symbian.h
@@ -0,0 +1,56 @@
+/* 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 OBJECTDUMP_SYMBIAN_H
+#define OBJECTDUMP_SYMBIAN_H
+
+#include "objectdump.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+namespace Symbian
+{
+
+/**
+ * Annotator which returns control information
+ */
+class QAnnotatorControl : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+/**
+ * Annotator which returns window information
+ */
+class QAnnotatorWindow : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+} // namespace Symbian
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/objecttree.cpp b/src/3rdparty/phonon/mmf/objecttree.cpp
new file mode 100644
index 0000000..f9d1c93
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objecttree.cpp
@@ -0,0 +1,102 @@
+/* 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 <QTextStream>
+#include <QWidget>
+#include "objecttree.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectTree
+{
+
+DepthFirstConstIterator::DepthFirstConstIterator()
+ : m_pointee(NULL)
+{
+
+}
+
+DepthFirstConstIterator::DepthFirstConstIterator
+ (const QObject& root)
+ : m_pointee(&root)
+{
+
+}
+
+DepthFirstConstIterator&
+ DepthFirstConstIterator::operator++()
+{
+ const QObjectList& children = m_pointee->children();
+
+ if (children.count() == 0) {
+ backtrack();
+ }
+ else {
+ m_history.push(0);
+ m_pointee = children.first();
+ }
+
+ return *this;
+}
+
+void DepthFirstConstIterator::backtrack()
+{
+ if (m_history.count()) {
+ const int index = m_history.top();
+ m_history.pop();
+
+ const QObjectList& siblings = m_pointee->parent()->children();
+ if (siblings.count() > index + 1) {
+ m_history.push(index + 1);
+ m_pointee = siblings[index + 1];
+ }
+ else {
+ m_pointee = m_pointee->parent();
+ backtrack();
+ }
+ }
+ else {
+ // Reached end of search
+ m_pointee = NULL;
+ }
+}
+
+
+
+AncestorConstIterator::AncestorConstIterator()
+{
+
+}
+
+AncestorConstIterator::AncestorConstIterator(const QObject& leaf)
+{
+ m_ancestors.push(&leaf);
+ QObject* ancestor = leaf.parent();
+ while(ancestor)
+ {
+ m_ancestors.push(ancestor);
+ ancestor = ancestor->parent();
+ }
+}
+
+} // namespace ObjectTree
+
+QT_END_NAMESPACE
+
+
+
diff --git a/src/3rdparty/phonon/mmf/objecttree.h b/src/3rdparty/phonon/mmf/objecttree.h
new file mode 100644
index 0000000..0c2031d
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objecttree.h
@@ -0,0 +1,115 @@
+/* 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 OBJECTTREE_H
+#define OBJECTTREE_H
+
+#include <QObject>
+#include <QStack>
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectTree
+{
+
+/**
+ * Depth-first iterator for QObject tree
+ */
+class DepthFirstConstIterator
+{
+public:
+ DepthFirstConstIterator();
+ DepthFirstConstIterator(const QObject& root);
+
+ DepthFirstConstIterator& operator++();
+
+ inline bool operator==(const DepthFirstConstIterator& other) const
+ { return other.m_pointee == m_pointee; }
+
+ inline bool operator!=(const DepthFirstConstIterator& other) const
+ { return other.m_pointee != m_pointee; }
+
+ inline const QObject* operator->() const { return m_pointee; }
+ inline const QObject& operator*() const { return *m_pointee; }
+
+private:
+ void backtrack();
+
+private:
+ const QObject* m_pointee;
+ QStack<int> m_history;
+};
+
+/**
+ * Ancestor iterator for QObject tree
+ */
+class AncestorConstIterator
+{
+public:
+ AncestorConstIterator();
+ AncestorConstIterator(const QObject& root);
+
+ inline AncestorConstIterator& operator++()
+ { m_ancestors.pop(); return *this; }
+
+ inline bool operator==(const AncestorConstIterator& other) const
+ { return other.m_ancestors == m_ancestors; }
+
+ inline bool operator!=(const AncestorConstIterator& other) const
+ { return other.m_ancestors != m_ancestors; }
+
+ inline const QObject* operator->() const { return m_ancestors.top(); }
+ inline const QObject& operator*() const { return *m_ancestors.top(); }
+
+private:
+ QStack<const QObject*> m_ancestors;
+
+};
+
+/**
+ * Generic algorithm for visiting nodes in an object tree. Nodes in the
+ * tree are visited in a const context, therefore they are not modified
+ * by this algorithm.
+ *
+ * Visitor must provide functions with the following signatures:
+ *
+ * Called before visit begins
+ * void visitPrepare()
+ *
+ * Called on each node visited
+ * void visitNode(const QObject& object)
+ *
+ * Called when visit is complete
+ * void visitComplete()
+ */
+template <class Iterator, class Visitor>
+void visit(Iterator begin, Iterator end, Visitor& visitor)
+{
+ visitor.visitPrepare();
+
+ for( ; begin != end; ++begin)
+ visitor.visitNode(*begin);
+
+ visitor.visitComplete();
+}
+
+} // namespace ObjectTree
+
+QT_END_NAMESPACE
+
+#endif // OBJECTTREE_H
diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp
index c517c22..2544a97 100644
--- a/src/3rdparty/phonon/mmf/videooutput.cpp
+++ b/src/3rdparty/phonon/mmf/videooutput.cpp
@@ -20,6 +20,10 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "videooutput.h"
#include "videooutputobserver.h"
+#ifdef _DEBUG
+#include "objectdump.h"
+#endif
+
#include <QPaintEvent>
#include <QPainter>
#include <QMoveEvent>
@@ -48,59 +52,10 @@ MMF::VideoOutput::VideoOutput(QWidget* parent)
setAutoFillBackground(false);
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
-#ifdef PHONON_MMF_DEBUG_VIDEO_OUTPUT
dump();
-#endif
-
- TRACE_EXIT_0();
-}
-
-#ifdef PHONON_MMF_DEBUG_VIDEO_OUTPUT
-void VideoOutput::dump()
-{
- TRACE_CONTEXT(VideoOutput::dump, EVideoInternal);
- TRACE_ENTRY_0();
-
- TRACE("dumpObjectInfo this 0x%08x", this);
- this->dumpObjectInfo();
-
- TRACE_0("Traversing up object tree ...");
- QObject* node = this;
- QObject* root = this;
- while (node) {
- QWidget* widget = qobject_cast<QWidget*>(node);
- const bool visible = widget ? widget->isVisible() : false;
- const QHBufC name(node->objectName());
- TRACE("node 0x%08x name %S widget 0x%08x visible %d", node, name.data(), widget, visible);
-
- root = node;
- node = node->parent();
- }
-
- TRACE("dumpObjectInfo root 0x%08x", root);
- root->dumpObjectInfo();
- TRACE_0("+ dumpObjectTree");
- root->dumpObjectTree();
- TRACE_0("- dumpObjectTree");
-
- TRACE("isVisible %d", isVisible());
- TRACE("pos %d %d", x(), y());
- TRACE("size %d %d", size().width(), size().height());
- TRACE("maxSize %d %d", maximumWidth(), maximumHeight());
- TRACE("sizeHint %d %d", sizeHint().width(), sizeHint().height());
-
- QWidget* parentWidget = qobject_cast<QWidget*>(parent());
- if (parentWidget) {
- TRACE("parent.isVisible %d", parentWidget->isVisible());
- TRACE("parent.pos %d %d", parentWidget->x(), parentWidget->y());
- TRACE("parent.size %d %d", parentWidget->size().width(), parentWidget->size().height());
- TRACE("parent.maxSize %d %d", parentWidget->maximumWidth(), parentWidget->maximumHeight());
- TRACE("parent.sizeHint %d %d", parentWidget->sizeHint().width(), parentWidget->sizeHint().height());
- }
-
+
TRACE_EXIT_0();
}
-#endif // PHONON_MMF_DEBUG_VIDEO_OUTPUT
MMF::VideoOutput::~VideoOutput()
{
@@ -144,8 +99,6 @@ void MMF::VideoOutput::setObserver(VideoOutputObserver* observer)
QSize MMF::VideoOutput::sizeHint() const
{
- TRACE_CONTEXT(VideoOutput::sizeHint, EVideoApi);
-
// TODO: replace this with a more sensible default
QSize result(320, 240);
@@ -153,7 +106,6 @@ QSize MMF::VideoOutput::sizeHint() const
result = m_frameSize;
}
- TRACE(" result %d %d", result.width(), result.height());
return result;
}
@@ -166,6 +118,8 @@ void MMF::VideoOutput::paintEvent(QPaintEvent* event)
TRACE("regions %d", event->region().numRects());
TRACE("type %d", event->type());
+ dump();
+
/*
QPainter painter;
painter.begin(this);
@@ -208,6 +162,19 @@ void MMF::VideoOutput::moveEvent(QMoveEvent* event)
// Private functions
//-----------------------------------------------------------------------------
+void VideoOutput::dump() const
+{
+#ifdef _DEBUG
+ TRACE_CONTEXT(VideoOutput::dump, EVideoInternal);
+ QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
+ visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
+ ObjectDump::addDefaultAnnotators(*visitor);
+ TRACE("Dumping tree from leaf 0x%08x:", this);
+ //ObjectDump::dumpAncestors(*this, *visitor);
+ ObjectDump::dumpTreeFromLeaf(*this, *visitor);
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h
index bcd9cb4..566d065 100644
--- a/src/3rdparty/phonon/mmf/videooutput.h
+++ b/src/3rdparty/phonon/mmf/videooutput.h
@@ -50,11 +50,9 @@ protected:
void moveEvent(QMoveEvent* event);
#endif // PHONON_MMF_VIDEOOUTPUT_IS_QWIDGET
-#ifdef PHONON_MMF_DEBUG_VIDEO_OUTPUT
-public:
- void dump();
-#endif
-
+private:
+ void dump() const;
+
private:
QSize m_frameSize;
diff --git a/src/3rdparty/phonon/mmf/videoplayer.cpp b/src/3rdparty/phonon/mmf/videoplayer.cpp
index 736d74f..a73c6ec 100644
--- a/src/3rdparty/phonon/mmf/videoplayer.cpp
+++ b/src/3rdparty/phonon/mmf/videoplayer.cpp
@@ -26,6 +26,10 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "videoplayer.h"
#include "utils.h"
+#ifdef _DEBUG
+#include "objectdump.h"
+#endif
+
QT_BEGIN_NAMESPACE
using namespace Phonon;
@@ -398,10 +402,17 @@ void MMF::VideoPlayer::videoOutputChanged()
void MMF::VideoPlayer::getNativeWindowSystemHandles()
{
TRACE_CONTEXT(VideoPlayer::getNativeWindowSystemHandles, EVideoInternal);
+ TRACE_ENTRY_0();
VideoOutput& output = videoOutput();
CCoeControl* const control = output.winId();
-
+
+ CCoeEnv* const coeEnv = control->ControlEnv();
+ m_wsSession = &(coeEnv->WsSession());
+ m_screenDevice = coeEnv->ScreenDevice();
+ m_window = control->DrawableWindow();
+
+/*
TRACE("control 0x%08x", control);
TRACE("control IsVisible %d", control->IsVisible());
TRACE("control IsDimmed %d", control->IsDimmed());
@@ -434,6 +445,15 @@ void MMF::VideoPlayer::getNativeWindowSystemHandles()
m_window->AbsPosition().iX, m_window->AbsPosition().iY);
TRACE("window Size %d %d",
m_window->Size().iWidth, m_window->Size().iHeight);
+*/
+
+#ifdef _DEBUG
+ QScopedPointer<ObjectDump::QDumper> dumper(new ObjectDump::QDumper);
+ dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs
+ ObjectDump::addDefaultAnnotators(*dumper);
+ TRACE_0("Dumping VideoOutput:");
+ dumper->dumpObject(output);
+#endif
#ifdef PHONON_MMF_HARD_CODE_VIDEO_RECT
// HACK: why isn't control->Rect updated following a call to
@@ -455,6 +475,8 @@ void MMF::VideoPlayer::getNativeWindowSystemHandles()
TRACE("clipRect %d %d - %d %d",
m_clipRect.iTl.iX, m_clipRect.iTl.iY,
m_clipRect.iBr.iX, m_clipRect.iBr.iY);
+
+ TRACE_EXIT_0();
}
diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro
index 1d9910b..56cc37a 100644
--- a/src/plugins/phonon/mmf/mmf.pro
+++ b/src/plugins/phonon/mmf/mmf.pro
@@ -49,6 +49,21 @@ SOURCES += \
$$PHONON_MMF_DIR/videooutput.cpp \
$$PHONON_MMF_DIR/videoplayer.cpp \
$$PHONON_MMF_DIR/videowidget.cpp
+
+# This is not mmfphonon-specific, and should be factored out into a separate
+# library (QtCore?) at a later date
+debug {
+HEADERS += \
+ $$PHONON_MMF_DIR/objectdump.h \
+ $$PHONON_MMF_DIR/objectdump_symbian.h \
+ $$PHONON_MMF_DIR/objecttree.h
+
+SOURCES += \
+ $$PHONON_MMF_DIR/objectdump.cpp \
+ $$PHONON_MMF_DIR/objectdump_symbian.cpp \
+ $$PHONON_MMF_DIR/objecttree.cpp
+
+}
LIBS += -lmediaclientvideo.lib # For CVideoPlayerUtility
LIBS += -lcone.lib # For CCoeEnv