From 884ea10d037d855b91ea5ef947b5c23d2f09aead Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Wed, 17 Feb 2010 23:04:34 +0100 Subject: Fix undefined sequence point compiler warning level = ++level is not guaranteed to work, as the increment is not required to happen before the assignment. Change this code to be less obscure and use standard defined behavior. Merge-request: 471 Reviewed-by: Thiago Macieira --- src/gui/kernel/qsoftkeymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 6d108b0..d89276f 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -215,7 +215,7 @@ bool QSoftKeyManager::handleUpdateSoftKeys() if (source) { bool added = appendSoftkeys(*source, level); source = softkeySource(source, recursiveMerging); - level = added ? ++level : level; + level = added ? level + 1 : level; } } while (source); -- cgit v0.12 From cdf4701f442149546043b155cddcc53116875f1c Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Wed, 17 Feb 2010 23:17:36 +0100 Subject: Fix s390(x) atomic ops related crashes The s390 implementation of the pointer related atomic ops never worked before, and the memory barrier was mixed up between the Acquire and the Relaxed variant. This fixes both. Merge-request: 2312 Reviewed-by: Thiago Macieira --- src/corelib/arch/qatomic_s390.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h index 21f5037..273c17b 100644 --- a/src/corelib/arch/qatomic_s390.h +++ b/src/corelib/arch/qatomic_s390.h @@ -366,11 +366,9 @@ template Q_INLINE_TEMPLATE T* QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast(_q_value), (int)newValue, "lr", - "", "bcr 15,0\n"); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", ""); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast(_q_value), (long)newValue, "lgr", - "", "bcr 15,0\n"); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", ""); #endif } @@ -378,9 +376,9 @@ template Q_INLINE_TEMPLATE T* QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast(_q_value), (int)newValue, "lr", "", ""); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n"); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast(_q_value), (long)newValue, "lgr", "", ""); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n"); #endif } @@ -388,11 +386,9 @@ template Q_INLINE_TEMPLATE T* QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast(_q_value), (int)newValue, "lr", - "bcr 15,0 \n", ""); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", ""); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast(_q_value), (long)newValue, "lgr", - "bcr 15,0\n", ""); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", ""); #endif } -- cgit v0.12 From c07f8354bec3c7b6d78f798589119ed0ab4f1332 Mon Sep 17 00:00:00 2001 From: ck Date: Fri, 12 Feb 2010 11:29:20 +0100 Subject: Help system: Handle all Clucene exceptions. Reviewed-by: kh1 --- .../lib/qhelpsearchindexwriter_clucene.cpp | 230 ++++++++++----------- 1 file changed, 112 insertions(+), 118 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index e3cc2b0..2eeefb5 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -613,67 +613,69 @@ void QHelpSearchIndexWriter::optimizeIndex() void QHelpSearchIndexWriter::run() { - QMutexLocker mutexLocker(&mutex); +#if !defined(QT_NO_EXCEPTIONS) + try { +#endif + QMutexLocker mutexLocker(&mutex); - if (m_cancel) - return; + if (m_cancel) + return; - const bool reindex = this->m_reindex; - const QString collectionFile(this->m_collectionFile); + const bool reindex = this->m_reindex; + const QString collectionFile(this->m_collectionFile); - mutexLocker.unlock(); + mutexLocker.unlock(); - QHelpEngineCore engine(collectionFile, 0); - if (!engine.setupData()) - return; + QHelpEngineCore engine(collectionFile, 0); + if (!engine.setupData()) + return; - const QLatin1String key("CluceneIndexedNamespaces"); - if (reindex) - engine.setCustomValue(key, QLatin1String("")); - - QMap indexMap; - const QLatin1String oldKey("CluceneSearchNamespaces"); - if (!engine.customValue(oldKey, QString()).isNull()) { - // old style qhc file < 4.4.2, need to convert... - const QStringList indexedNamespaces = engine.customValue(oldKey). - toString().split(QLatin1String("|"), QString::SkipEmptyParts); - foreach (const QString &nameSpace, indexedNamespaces) - indexMap.insert(nameSpace, QDateTime()); - engine.removeCustomValue(oldKey); - } else { - QDataStream dataStream(engine.customValue(key).toByteArray()); - dataStream >> indexMap; - } + const QLatin1String key("CluceneIndexedNamespaces"); + if (reindex) + engine.setCustomValue(key, QLatin1String("")); + + QMap indexMap; + const QLatin1String oldKey("CluceneSearchNamespaces"); + if (!engine.customValue(oldKey, QString()).isNull()) { + // old style qhc file < 4.4.2, need to convert... + const QStringList indexedNamespaces + = engine.customValue(oldKey).toString() + .split(QLatin1String("|"), QString::SkipEmptyParts); + foreach (const QString &nameSpace, indexedNamespaces) + indexMap.insert(nameSpace, QDateTime()); + engine.removeCustomValue(oldKey); + } else { + QDataStream dataStream(engine.customValue(key).toByteArray()); + dataStream >> indexMap; + } - QString indexPath = m_indexFilesFolder; + QString indexPath = m_indexFilesFolder; - QFileInfo fInfo(indexPath); - if (fInfo.exists() && !fInfo.isWritable()) { - qWarning("Full Text Search, could not create index (missing permissions for '%s').", qPrintable(indexPath)); - return; - } + QFileInfo fInfo(indexPath); + if (fInfo.exists() && !fInfo.isWritable()) { + qWarning("Full Text Search, could not create index (missing permissions for '%s').", + qPrintable(indexPath)); + return; + } - emit indexingStarted(); + emit indexingStarted(); - QCLuceneIndexWriter *writer = 0; - QCLuceneStandardAnalyzer analyzer; - const QStringList registeredDocs = engine.registeredDocumentations(); + QCLuceneIndexWriter *writer = 0; + QCLuceneStandardAnalyzer analyzer; + const QStringList registeredDocs = engine.registeredDocumentations(); - QLocalSocket localSocket; - localSocket.connectToServer(QString(QLatin1String("QtAssistant%1")) - .arg(QLatin1String(QT_VERSION_STR))); + QLocalSocket localSocket; + localSocket.connectToServer(QString(QLatin1String("QtAssistant%1")) + .arg(QLatin1String(QT_VERSION_STR))); - QLocalServer localServer; - bool otherInstancesRunning = true; - if (!localSocket.waitForConnected()) { - otherInstancesRunning = false; - localServer.listen(QString(QLatin1String("QtAssistant%1")) - .arg(QLatin1String(QT_VERSION_STR))); - } + QLocalServer localServer; + bool otherInstancesRunning = true; + if (!localSocket.waitForConnected()) { + otherInstancesRunning = false; + localServer.listen(QString(QLatin1String("QtAssistant%1")) + .arg(QLatin1String(QT_VERSION_STR))); + } -#if !defined(QT_NO_EXCEPTIONS) - try { -#endif // check if it's locked, and if the other instance is running if (!otherInstancesRunning && QCLuceneIndexReader::isLocked(indexPath)) QCLuceneIndexReader::unlock(indexPath); @@ -705,7 +707,8 @@ void QHelpSearchIndexWriter::run() removeDocuments(indexPath, namespaceName); } else { QString path = engine.documentationFileName(namespaceName); - if (indexMap.value(namespaceName) < QFileInfo(path).lastModified()) { + if (indexMap.value(namespaceName) + < QFileInfo(path).lastModified()) { // make sure we remove some outdated indexed stuff indexMap.remove(namespaceName); removeDocuments(indexPath, namespaceName); @@ -728,94 +731,85 @@ void QHelpSearchIndexWriter::run() indexMap.clear(); writer = new QCLuceneIndexWriter(indexPath, analyzer, true); } -#if !defined(QT_NO_EXCEPTIONS) - } catch (...) { - qWarning("Full Text Search, could not create index writer in '%s'.", - qPrintable(indexPath)); - return; - } -#endif -#if !defined(QT_NO_EXCEPTIONS) - try { -#endif writer->setMergeFactor(100); writer->setMinMergeDocs(1000); writer->setMaxFieldLength(QCLuceneIndexWriter::DEFAULT_MAX_FIELD_LENGTH); -#if !defined(QT_NO_EXCEPTIONS) - } catch (...) { - qWarning("Full Text Search, could not set writer properties."); - return; - } -#endif - QStringList namespaces; - foreach(const QString &namespaceName, registeredDocs) { - mutexLocker.relock(); - if (m_cancel) { - closeIndexWriter(writer); - emit indexingFinished(); - return; - } - mutexLocker.unlock(); + QStringList namespaces; + foreach(const QString &namespaceName, registeredDocs) { + mutexLocker.relock(); + if (m_cancel) { + closeIndexWriter(writer); + emit indexingFinished(); + return; + } + mutexLocker.unlock(); - namespaces.append(namespaceName); - if (indexMap.contains(namespaceName)) - continue; + namespaces.append(namespaceName); + if (indexMap.contains(namespaceName)) + continue; - const QList attributeSets = - engine.filterAttributeSets(namespaceName); + const QList attributeSets = + engine.filterAttributeSets(namespaceName); - if (attributeSets.isEmpty()) { - const QList docFiles = indexableFiles(&engine, namespaceName, - QStringList()); - if (!addDocuments(docFiles, engine, QStringList(), namespaceName, - writer, analyzer)) - break; - } else { - bool bail = false; - foreach (const QStringList &attributes, attributeSets) { - const QList docFiles = indexableFiles(&engine, - namespaceName, attributes); - if (!addDocuments(docFiles, engine, attributes, namespaceName, - writer, analyzer)) { - bail = true; + if (attributeSets.isEmpty()) { + const QList docFiles = indexableFiles(&engine, namespaceName, + QStringList()); + if (!addDocuments(docFiles, engine, QStringList(), namespaceName, + writer, analyzer)) break; + } else { + bool bail = false; + foreach (const QStringList &attributes, attributeSets) { + const QList docFiles = indexableFiles(&engine, + namespaceName, attributes); + if (!addDocuments(docFiles, engine, attributes, namespaceName, + writer, analyzer)) { + bail = true; + break; + } } + if (bail) + break; } - if (bail) - break; - } - mutexLocker.relock(); - if (!m_cancel) { - QString path(engine.documentationFileName(namespaceName)); - indexMap.insert(namespaceName, QFileInfo(path).lastModified()); - writeIndexMap(engine, indexMap); + mutexLocker.relock(); + if (!m_cancel) { + QString path(engine.documentationFileName(namespaceName)); + indexMap.insert(namespaceName, QFileInfo(path).lastModified()); + writeIndexMap(engine, indexMap); + } + mutexLocker.unlock(); } - mutexLocker.unlock(); - } - closeIndexWriter(writer); + closeIndexWriter(writer); - mutexLocker.relock(); - if (!m_cancel) { - mutexLocker.unlock(); - - QStringList indexedNamespaces = indexMap.keys(); - foreach(const QString &namespaceName, indexedNamespaces) { - mutexLocker.relock(); - if (m_cancel) - break; + mutexLocker.relock(); + if (!m_cancel) { mutexLocker.unlock(); - if (!namespaces.contains(namespaceName)) { - indexMap.remove(namespaceName); - writeIndexMap(engine, indexMap); - removeDocuments(indexPath, namespaceName); + QStringList indexedNamespaces = indexMap.keys(); + foreach(const QString &namespaceName, indexedNamespaces) { + mutexLocker.relock(); + if (m_cancel) + break; + mutexLocker.unlock(); + + if (!namespaces.contains(namespaceName)) { + indexMap.remove(namespaceName); + writeIndexMap(engine, indexMap); + removeDocuments(indexPath, namespaceName); + } } } + +#if !defined(QT_NO_EXCEPTIONS) + } catch (...) { + qWarning("%s: Failed because of CLucene exception.", Q_FUNC_INFO); } +#endif + emit indexingFinished(); } -- cgit v0.12 From 92465142116ed140b4323c4a8f5bc325c45cdccf Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Thu, 18 Feb 2010 11:06:49 +0200 Subject: QWebView scrolling doesn't clear old elements before painting again Author: Petri Date: Wed Feb 10 12:27:19 2010 +0200 Patch to QTBUG-7286 QWebView scrolling doesn't clear old elements before painting on top of them. The bug exists only if web page does not set its backgroung color. Solution is to set White color as a default color for web page backgrounds. White color was causing some visibility problem (at least with lineedit) and it was solved by editing ::canDrawThemeBackground Task-number: QTBUG-7286 Reviewed-by: Sami Merila --- src/gui/styles/qs60style.cpp | 23 ++++++++++++++++------- src/gui/styles/qs60style_p.h | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ea7399f..74707af 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -120,6 +120,8 @@ QPixmap *QS60StylePrivate::m_background = 0; // theme palette QPalette *QS60StylePrivate::m_themePalette = 0; +qint64 QS60StylePrivate::m_webPaletteKey = 0; + const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, @@ -807,8 +809,12 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const QPalette webPalette = *palette; webPalette.setColor(QPalette::WindowText, Qt::black); webPalette.setColor(QPalette::Text, Qt::black); + webPalette.setBrush(QPalette::Base, Qt::white); + QApplication::setPalette(webPalette, "QWebView"); QApplication::setPalette(webPalette, "QGraphicsWebView"); + + m_webPaletteKey = webPalette.cacheKey(); } QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags) @@ -896,8 +902,11 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag return result; } -bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) +bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget) { + // Always return true for web pages. + if (widget && m_webPaletteKey == QApplication::palette(widget).cacheKey()) + return true; //If brush is not changed from style's default values, draw theme graphics. return (backgroundBrush.color() == Qt::transparent || backgroundBrush.style() == Qt::NoBrush) ? true : false; @@ -1901,7 +1910,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, case CE_ShapedFrame: if (const QTextEdit *textEdit = qobject_cast(widget)) { const QStyleOptionFrame *frame = qstyleoption_cast(option); - if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base())) + if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget)) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); else QCommonStyle::drawControl(element, option, painter, widget); @@ -2013,7 +2022,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (widget && qobject_cast(widget->parentWidget())) break; #endif - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, painter, option->rect, flags); else commonStyleDraws = true; @@ -2093,7 +2102,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_PanelButtonTool: case PE_PanelButtonBevel: case PE_FrameButtonBevel: - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) { const bool isPressed = option->state & State_Sunken; const QS60StylePrivate::SkinElements skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; @@ -2125,7 +2134,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorSpinDown: case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base(), widget)) { QStyleOptionSpinBox optionSpinBox = *spinBox; const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? QS60StyleEnums::SP_QgnGrafScrollArrowUp : @@ -2140,7 +2149,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti #endif //QT_NO_SPINBOX #ifndef QT_NO_COMBOBOX if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { - if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground( option->palette.base(), widget)) { // We want to draw down arrow here for comboboxes as well. QStyleOptionFrame optionsComboBox = *cmb; const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; @@ -2179,7 +2188,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti #endif //QT_NO_MENU ) { //Need extra check since dialogs have their own theme background - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) && + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && option->palette.window().texture().cacheKey() == QS60StylePrivate::m_themePalette->window().texture().cacheKey()) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags); diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index ea30b81..16d82e7 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -542,7 +542,7 @@ public: //Checks that the current brush is transparent or has BrushStyle NoBrush, //so that theme graphic background can be drawn. - static bool canDrawThemeBackground(const QBrush &backgroundBrush); + static bool canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget); static int currentAnimationFrame(QS60StyleEnums::SkinParts part); #ifdef Q_WS_S60 @@ -596,6 +596,7 @@ private: QPalette m_originalPalette; QPointer m_focusFrame; + static qint64 m_webPaletteKey; #ifdef Q_WS_S60 //list of progress bars having animation running -- cgit v0.12 From 4971430290ecb11012ef5cbf8ef041da0ec3a824 Mon Sep 17 00:00:00 2001 From: Zeno Albisser Date: Thu, 18 Feb 2010 11:16:26 +0100 Subject: Revert "Added note to make QList destructor virtual in version 5" Virtual functions should not be used with copyable types due to slicing. This reverts commit c1db6c2c5a3bbe96a628207af169a032d535426f. --- src/corelib/tools/qlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index a549f2f..1ad7528 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -112,7 +112,7 @@ class QList public: inline QList() : d(&QListData::shared_null) { d->ref.ref(); } inline QList(const QList &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); } - ~QList(); // ### Qt5: make this destructor virtual + ~QList(); QList &operator=(const QList &l); bool operator==(const QList &l) const; inline bool operator!=(const QList &l) const { return !(*this == l); } -- cgit v0.12 From 2e8af9b06f7c25710253e517325644b5fa1ba17f Mon Sep 17 00:00:00 2001 From: ck Date: Thu, 18 Feb 2010 11:21:11 +0100 Subject: Help system: Remove hard-coded qt namespace. Task-number: QTBUG-7821 Reviewed-by: kh1 --- tools/assistant/lib/qhelpsearchengine.cpp | 6 +++--- tools/assistant/lib/qhelpsearchindexreader.cpp | 6 ++---- tools/assistant/lib/qhelpsearchindexreader_clucene.cpp | 10 ++++------ tools/assistant/lib/qhelpsearchindexreader_clucene_p.h | 10 ++++------ tools/assistant/lib/qhelpsearchindexreader_default.cpp | 10 ++++------ tools/assistant/lib/qhelpsearchindexreader_default_p.h | 10 ++++------ tools/assistant/lib/qhelpsearchindexreader_p.h | 6 ++---- tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp | 10 ++++------ tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h | 9 ++++----- tools/assistant/lib/qhelpsearchindexwriter_default.cpp | 10 ++++------ tools/assistant/lib/qhelpsearchindexwriter_default_p.h | 10 ++++------ 11 files changed, 39 insertions(+), 58 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp index 7c2635d..9914efa 100644 --- a/tools/assistant/lib/qhelpsearchengine.cpp +++ b/tools/assistant/lib/qhelpsearchengine.cpp @@ -63,9 +63,9 @@ QT_BEGIN_NAMESPACE #if defined(QT_CLUCENE_SUPPORT) - using namespace qt::fulltextsearch::clucene; + using namespace fulltextsearch::clucene; #else - using namespace qt::fulltextsearch::std; + using namespace fulltextsearch::std; #endif class QHelpSearchEnginePrivate : public QObject @@ -195,7 +195,7 @@ private: QHelpSearchQueryWidget *queryWidget; QHelpSearchResultWidget *resultWidget; - qt::fulltextsearch::QHelpSearchIndexReader *indexReader; + fulltextsearch::QHelpSearchIndexReader *indexReader; QHelpSearchIndexWriter *indexWriter; QPointer helpEngine; diff --git a/tools/assistant/lib/qhelpsearchindexreader.cpp b/tools/assistant/lib/qhelpsearchindexreader.cpp index 92d7658..e79fca6 100644 --- a/tools/assistant/lib/qhelpsearchindexreader.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader.cpp @@ -43,8 +43,7 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { +namespace fulltextsearch { QHelpSearchIndexReader::QHelpSearchIndexReader() : QThread() @@ -100,7 +99,6 @@ QList QHelpSearchIndexReader::hits(int start, } - } // namespace fulltextsearch -} // namespace qt +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index b5bec44..b050361 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -55,9 +55,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace clucene { +namespace fulltextsearch { +namespace clucene { QHelpSearchIndexReaderClucene::QHelpSearchIndexReaderClucene() : QHelpSearchIndexReader() @@ -387,8 +386,7 @@ void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engin } } - } // namespace clucene - } // namespace fulltextsearch -} // namespace qt +} // namespace clucene +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index 3e3b9dd..8f51cb1 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -60,9 +60,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace clucene { +namespace fulltextsearch { +namespace clucene { class QHelpSearchIndexReaderClucene : public QHelpSearchIndexReader { @@ -84,9 +83,8 @@ private: const QList &queryList); }; - } // namespace clucene - } // namespace fulltextsearch -} // namespace qt +} // namespace clucene +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexreader_default.cpp b/tools/assistant/lib/qhelpsearchindexreader_default.cpp index d2241a5..11a50d9 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_default.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_default.cpp @@ -52,9 +52,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace std { +namespace fulltextsearch { +namespace std { namespace { QStringList split( const QString &str ) @@ -607,8 +606,7 @@ void QHelpSearchIndexReaderDefault::run() emit searchingFinished(hitList.count()); } - } // namespace std - } // namespace fulltextsearch -} // namespace qt +} // namespace std +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexreader_default_p.h b/tools/assistant/lib/qhelpsearchindexreader_default_p.h index 8c80608..b30fa4b 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_default_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_default_p.h @@ -64,9 +64,8 @@ QT_BEGIN_NAMESPACE struct Entry; struct PosEntry; -namespace qt { - namespace fulltextsearch { - namespace std { +namespace fulltextsearch { +namespace std { class Reader { @@ -127,9 +126,8 @@ private: Reader m_reader; }; - } // namespace std - } // namespace fulltextsearch -} // namespace qt +} // namespace std +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexreader_p.h b/tools/assistant/lib/qhelpsearchindexreader_p.h index b309f46..4d27c0f 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_p.h @@ -66,8 +66,7 @@ QT_BEGIN_NAMESPACE class QHelpEngineCore; -namespace qt { - namespace fulltextsearch { +namespace fulltextsearch { class QHelpSearchIndexReader : public QThread { @@ -100,8 +99,7 @@ private: virtual void run()=0; }; - } // namespace fulltextsearch -} // namespace qt +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index 2eeefb5..59067cf 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -63,9 +63,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace clucene { +namespace fulltextsearch { +namespace clucene { // taken from qtexthtmlparser static const struct QTextHtmlEntity @@ -895,8 +894,7 @@ void QHelpSearchIndexWriter::closeIndexWriter(QCLuceneIndexWriter *writer) #endif } - } // namespace clucene - } // namespace fulltextsearch -} // namespace qt +} // namespace clucene +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h b/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h index 91b8abd..db1e533 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene_p.h @@ -69,9 +69,8 @@ QT_BEGIN_NAMESPACE class QCLuceneIndexWriter; -namespace qt { - namespace fulltextsearch { - namespace clucene { +namespace fulltextsearch { +namespace clucene { class QHelpSearchIndexWriter : public QThread { @@ -116,9 +115,9 @@ private: QString m_indexFilesFolder; }; - } // namespace clucene - } // namespace fulltextsearch } // namespace clucene +} // namespace fulltextsearch + QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp index 6d09fb8..cb3e49c 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp @@ -55,9 +55,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace std { +namespace fulltextsearch { +namespace std { Writer::Writer(const QString &path) : indexPath(path) @@ -379,8 +378,7 @@ QString QHelpSearchIndexWriter::removeNamespace(const QString namespaces, return value; } - } // namespace std - } // namespace fulltextsearch -} // namespace qt +} // namespace std +} // namespace fulltextsearch QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default_p.h b/tools/assistant/lib/qhelpsearchindexwriter_default_p.h index b222203..625cb84 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_default_p.h +++ b/tools/assistant/lib/qhelpsearchindexwriter_default_p.h @@ -65,9 +65,8 @@ QT_BEGIN_NAMESPACE -namespace qt { - namespace fulltextsearch { - namespace std { +namespace fulltextsearch { +namespace std { class Writer { @@ -123,9 +122,8 @@ private: QString m_indexFilesFolder; }; - } // namespace std - } // namespace fulltextsearch -} // namespace qt +} // namespace std +} // namespace fulltextsearch QT_END_NAMESPACE -- cgit v0.12 From a4332ce058cf3fe567b386d300ba740442a69f44 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 17 Feb 2010 16:36:40 +0100 Subject: QNAM HTTP: Always set channel.reply to 0 when done This will help us to track down a sporadic bug that made requests being sent again even if they were already done. Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 12 +----------- src/network/access/qhttpnetworkconnection_p.h | 5 ----- src/network/access/qhttpnetworkconnectionchannel.cpp | 17 ++++++++++++++--- src/network/access/qhttpnetworkreply.cpp | 13 ++++++++++--- src/network/access/qhttpnetworkreply_p.h | 2 ++ 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index cc6a1c8..327d2db 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -404,6 +404,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor QHttpNetworkReply *reply = new QHttpNetworkReply(request.url()); reply->setRequest(request); reply->d_func()->connection = q; + reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later HttpMessagePair pair = qMakePair(request, reply); switch (request.priority()) { @@ -861,17 +862,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const // SSL support below #ifndef QT_NO_OPENSSL -QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const -{ - if (!encrypt) - return QSslConfiguration(); - - for (int i = 0; i < channelCount; ++i) - if (channels[i].reply == &reply) - return static_cast(channels[0].socket)->sslConfiguration(); - return QSslConfiguration(); // pending or done request -} - void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config) { Q_D(QHttpNetworkConnection); diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 03cf09c..823774e 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -210,11 +210,6 @@ public: void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); - -#ifndef QT_NO_OPENSSL - QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; -#endif - #ifndef QT_NO_NETWORKPROXY QNetworkProxy networkProxy; void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 2a3036b..89fd032 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -137,6 +137,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() if (reply) { reply->d_func()->clear(); reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = false; } @@ -568,7 +569,8 @@ void QHttpNetworkConnectionChannel::allDone() handleStatus(); // ### at this point there should be no more data on the socket // close if server requested - if (reply->d_func()->isConnectionCloseEnabled()) + bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled(); + if (connectionCloseEnabled) close(); // queue the finished signal, this is required since we might send new requests from // slot connected to it. The socket will not fire readyRead signal, if we are already @@ -579,14 +581,22 @@ void QHttpNetworkConnectionChannel::allDone() // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; + detectPipeliningSupport(); + // now the channel can be seen as free/idle again, all signal emissions for the reply have been done this->state = QHttpNetworkConnectionChannel::IdleState; - detectPipeliningSupport(); + // if it does not need to be sent again we can set it to 0 + // the previous code did not do that and we had problems with accidental re-sending of a + // finished request. + // Note that this may trigger a segfault at some other point. But then we can fix the underlying + // problem. + if (!resendCurrent) + reply = 0; // move next from pipeline to current request if (!alreadyPipelinedRequests.isEmpty()) { - if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) { + if (resendCurrent || connectionCloseEnabled || socket->state() != QAbstractSocket::ConnectedState) { // move the pipelined ones back to the main queue requeueCurrentlyPipelinedRequests(); close(); @@ -745,6 +755,7 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) if (reply) { reply->d_func()->clear(); reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = true; } diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 512c045..984f557 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -230,6 +230,7 @@ void QHttpNetworkReplyPrivate::clear() currentChunkRead = 0; connectionCloseEnabled = true; connection = 0; + connectionChannel = 0; #ifndef QT_NO_COMPRESS if (initInflate) inflateEnd(&inflateStrm); @@ -803,9 +804,15 @@ void QHttpNetworkReplyPrivate::eraseData() QSslConfiguration QHttpNetworkReply::sslConfiguration() const { Q_D(const QHttpNetworkReply); - if (d->connection) - return d->connection->d_func()->sslConfiguration(*this); - return QSslConfiguration(); + + if (!d->connectionChannel) + return QSslConfiguration(); + + QSslSocket *sslSocket = qobject_cast(d->connectionChannel->socket); + if (!sslSocket) + return QSslConfiguration(); + + return sslSocket->sslConfiguration(); } void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config) diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index af9266b..fa240ec 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -86,6 +86,7 @@ static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header QT_BEGIN_NAMESPACE class QHttpNetworkConnection; +class QHttpNetworkConnectionChannel; class QHttpNetworkRequest; class QHttpNetworkConnectionPrivate; class QHttpNetworkReplyPrivate; @@ -218,6 +219,7 @@ public: qint64 currentChunkSize; qint64 currentChunkRead; QPointer connection; + QPointer connectionChannel; bool initInflate; bool streamEnd; #ifndef QT_NO_COMPRESS -- cgit v0.12 From 90c3e1d2110c47ad36e05c04c874d6d932dd772f Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 18 Feb 2010 14:41:20 +0100 Subject: QNAM HTTP: Clean code a bit .. and some changes that will help us track down bugs Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 10 ++-- .../access/qhttpnetworkconnectionchannel.cpp | 64 ++++++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 327d2db..62aa2d7 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -689,14 +689,12 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() if (channels[i].resendCurrent) { channels[i].resendCurrent = false; channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) { - // if this is not possible, error will be emitted and connection terminated - if (!channels[i].resetUploadData()) - continue; + // if this is not possible, error will be emitted and connection terminated + if (!channels[i].resetUploadData()) + continue; - channels[i].sendRequest(); - } + channels[i].sendRequest(); } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 89fd032..dbee72a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -124,6 +124,13 @@ void QHttpNetworkConnectionChannel::close() bool QHttpNetworkConnectionChannel::sendRequest() { + if (!reply) { + // heh, how should that happen! + qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply"; + state = QHttpNetworkConnectionChannel::IdleState; + return false; + } + switch (state) { case QHttpNetworkConnectionChannel::IdleState: { // write the header if (!ensureConnection()) { @@ -134,14 +141,13 @@ bool QHttpNetworkConnectionChannel::sendRequest() } written = 0; // excluding the header bytesTotal = 0; - if (reply) { - reply->d_func()->clear(); - reply->d_func()->connection = connection; - reply->d_func()->connectionChannel = this; - reply->d_func()->autoDecompress = request.d->autoDecompress; - reply->d_func()->pipeliningUsed = false; - } - state = QHttpNetworkConnectionChannel::WritingState; + + reply->d_func()->clear(); + reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; + reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = false; + pendingEncrypt = false; // if the url contains authentication parameters, use the new ones // both channels will use the new authentication parameters @@ -175,13 +181,15 @@ bool QHttpNetworkConnectionChannel::sendRequest() QObject::connect(uploadByteDevice, SIGNAL(readyRead()),this, SLOT(_q_uploadDataReadyRead())); bytesTotal = request.contentLength(); + + state = QHttpNetworkConnectionChannel::WritingState; // start writing data + sendRequest(); //recurse } else { - state = QHttpNetworkConnectionChannel::WaitingState; - sendRequest(); - break; + state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response + sendRequest(); //recurse } - // write the initial chunk together with the headers - // fall through + + break; } case QHttpNetworkConnectionChannel::WritingState: { @@ -191,7 +199,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() if (uploadByteDevice) emit reply->dataSendProgress(written, bytesTotal); state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response - sendRequest(); + sendRequest(); // recurse break; } @@ -279,16 +287,25 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); + if (!reply) { + // heh, how should that happen! + qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply," + << socket->bytesAvailable() << "bytes on socket."; + close(); + return; + } + qint64 bytes = 0; QAbstractSocket::SocketState socketState = socket->state(); // connection might be closed to signal the end of data if (socketState == QAbstractSocket::UnconnectedState) { if (socket->bytesAvailable() <= 0) { - if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { + if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { // finish this reply. this case happens when the server did not send a content length reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; allDone(); + return; } else { handleUnexpectedEOF(); return; @@ -300,12 +317,13 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() // read loop for the response while (socket->bytesAvailable()) { - QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; + QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state; switch (state) { case QHttpNetworkReplyPrivate::NothingDoneState: { // only eat whitespace on the first call eatWhitespace(); state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState; + // fallthrough } case QHttpNetworkReplyPrivate::ReadingStatusState: { qint64 statusBytes = reply->d_func()->readStatus(socket); @@ -413,8 +431,10 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() #endif } } + // still in ReadingDataState? This function will be called again by the socket's readyRead if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) break; + // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: @@ -752,13 +772,11 @@ void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) QHttpNetworkRequest &request = pair.first; QHttpNetworkReply *reply = pair.second; - if (reply) { - reply->d_func()->clear(); - reply->d_func()->connection = connection; - reply->d_func()->connectionChannel = this; - reply->d_func()->autoDecompress = request.d->autoDecompress; - reply->d_func()->pipeliningUsed = true; - } + reply->d_func()->clear(); + reply->d_func()->connection = connection; + reply->d_func()->connectionChannel = this; + reply->d_func()->autoDecompress = request.d->autoDecompress; + reply->d_func()->pipeliningUsed = true; #ifndef QT_NO_NETWORKPROXY QByteArray header = QHttpNetworkRequestPrivate::header(request, -- cgit v0.12 From 9d8614d8dcd1ae8389842aa4c48d8c77ae69bf27 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 18 Feb 2010 15:11:10 +0100 Subject: tst_qnetworkreply: Add another testcase Reviewed-by: Peter Hartmann --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 5fecc86..049bbb8 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -257,6 +257,8 @@ private Q_SLOTS: void httpConnectionCount(); + void httpRecursiveCreation(); + #ifndef QT_NO_OPENSSL void ioPostToHttpsUploadProgress(); void ignoreSslErrorsList_data(); @@ -3788,6 +3790,70 @@ void tst_QNetworkReply::httpConnectionCount() #endif } +class HttpRecursiveCreationHelper : public QObject { + Q_OBJECT +public: + + HttpRecursiveCreationHelper(): + QObject(0), + requestsStartedCount_finished(0), + requestsStartedCount_readyRead(0), + requestsFinishedCount(0) + { + } + QNetworkAccessManager manager; + int requestsStartedCount_finished; + int requestsStartedCount_readyRead; + int requestsFinishedCount; +public slots: + void finishedSlot() { + requestsFinishedCount++; + + QNetworkReply *reply = qobject_cast(sender()); + QVERIFY(!reply->error()); + QVERIFY(reply->bytesAvailable() == 27906); + + if (requestsFinishedCount == 60) { + QTestEventLoop::instance().exitLoop(); + return; + } + + if (requestsStartedCount_finished < 30) { + startOne(); + requestsStartedCount_finished++; + } + + reply->deleteLater(); + } + void readyReadSlot() { + QNetworkReply *reply = qobject_cast(sender()); + QVERIFY(!reply->error()); + + if (requestsStartedCount_readyRead < 30 && reply->bytesAvailable() > 27906/2) { + startOne(); + requestsStartedCount_readyRead++; + } + } + void startOne() { + QUrl url = "http://" + QtNetworkSettings::serverName() + "/gif/fluke.gif"; + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + reply->setParent(this); + connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot())); + connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + } +}; + +void tst_QNetworkReply::httpRecursiveCreation() +{ + // this test checks if creation of new requests to the same host properly works + // from readyRead() and finished() signals + HttpRecursiveCreationHelper helper; + helper.startOne(); + QTestEventLoop::instance().enterLoop(30); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + #ifndef QT_NO_OPENSSL void tst_QNetworkReply::ignoreSslErrorsList_data() { -- cgit v0.12 From f641369ceb7b7e2f95b9d0656b34c0517c5b95f7 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 13:20:09 +0000 Subject: Factored readRegistryKey implementation out of qmake This function is now implemented with its own header and source files, rather than being embedded within the MSVC qmake generator. The motivation for this is to allow code to be shared between qmake and configure, both of which query the registry when built for Windows. Reviewed-by: Miikka Heikkinen --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 7 ++ qmake/Makefile.win32-g++ | 5 + qmake/Makefile.win32-g++-sh | 5 + qmake/generators/win32/msvc_vcproj.cpp | 97 +------------------- qmake/qmake.pri | 7 +- qmake/qmake.pro | 4 + tools/shared/windows/registry.cpp | 161 +++++++++++++++++++++++++++++++++ tools/shared/windows/registry.h | 64 +++++++++++++ 9 files changed, 259 insertions(+), 100 deletions(-) create mode 100644 tools/shared/windows/registry.cpp create mode 100644 tools/shared/windows/registry.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index fcf43c8..e343803 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -10,7 +10,8 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ mingw_make.o option.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ - symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o + symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ + registry.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -20,6 +21,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ + registry.o \ $(QTOBJS) @@ -32,6 +34,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/makefiledeps.cpp option.cpp generators/win32/mingw_make.cpp generators/makefile.cpp \ generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ + $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -62,6 +65,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \ -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \ -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \ + -I$(BUILD_PATH)/tools/shared \ -DQT_NO_PCRE \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \ @@ -281,6 +285,9 @@ symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index e6bbcd5..3cd180c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -34,6 +34,7 @@ CFLAGS = -c -Fo$@ \ -I$(BUILD_PATH)\src\corelib\global \ -I$(BUILD_PATH)\src\corelib\xml \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \ @@ -59,6 +60,7 @@ CFLAGS = -c -o$@ \ -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \ -I$(BUILD_PATH)\src\corelib\global \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT @@ -75,6 +77,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ + registry.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -198,6 +201,7 @@ clean:: -del symmake_abld.obj -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj + -del registry.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -397,6 +401,9 @@ symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ade379b..ebc7fe2 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -278,6 +280,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 8d2723c..1d55da2 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -277,6 +279,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 47986f5..58f95e9 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -67,6 +67,7 @@ QT_END_NAMESPACE #ifdef Q_OS_WIN32 #include +#include QT_BEGIN_NAMESPACE @@ -93,102 +94,6 @@ struct { {NETUnknown, "", ""}, }; -static QString keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -static QString keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == "Default" || res == ".") - res = ""; - return res; -} - -static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) -{ - - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = 0; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); - - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - QString result; - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(", "); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); - break; - } - - RegCloseKey(handle); - return result; -} QT_END_NAMESPACE #endif diff --git a/qmake/qmake.pri b/qmake/qmake.pri index efe4f36..a2ffe15 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -17,7 +17,8 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ - generators/symbian/initprojectdeploy_symbian.cpp + generators/symbian/initprojectdeploy_symbian.cpp \ + windows/registry.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -29,8 +30,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ - generators/symbian/epocroot.h \ - generators/symbian/initprojectdeploy_symbian.h + generators/symbian/initprojectdeploy_symbian.h \ + windows/registry.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 00dcbce..f3f9d53 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -27,5 +27,9 @@ INCPATH += generators \ $$QT_SOURCE_TREE/include \ $$QT_SOURCE_TREE/include/QtCore \ $$QT_SOURCE_TREE/qmake + +VPATH += $$QT_SOURCE_TREE/tools/shared +INCPATH += $$QT_SOURCE_TREE/tools/shared + include(qmake.pri) diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp new file mode 100644 index 0000000..d342d78 --- /dev/null +++ b/tools/shared/windows/registry.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "registry.h" + +/*! + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/*! + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == "Default" || res == ".") + res = ""; + return res; +} + +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = 0; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(", "); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %d type in windows registry", dataType); + break; + } + + RegCloseKey(handle); +#endif + + return result; +} + + diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry.h new file mode 100644 index 0000000..3896527 --- /dev/null +++ b/tools/shared/windows/registry.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWS_REGISTRY_H +#define WINDOWS_REGISTRY_H + +#include + +#ifdef Q_OS_WIN32 + #include +#else + typedef void* HKEY; +#endif + +#include + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + */ +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey); + +#endif // WINDOWS_REGISTRY_H -- cgit v0.12 From 13cb80be958c40077245cbc4b36448a661e30c64 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 14:57:51 +0000 Subject: Factored epocRoot implementation out of qmake This function is now implemented in its own source file, rather than being embedded within the Symbian qmake generator. The motivation for this is to allow code to be shared between qmake and configure - the latter needs to determine the epoc root path in order to perform feature detection on Symbian SDKs. Reviewed-by: Miikka Heikkinen --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 5 + qmake/Makefile.win32-g++ | 4 + qmake/Makefile.win32-g++-sh | 4 + qmake/generators/symbian/epocroot.h | 51 ----- .../symbian/initprojectdeploy_symbian.cpp | 96 +-------- .../generators/symbian/initprojectdeploy_symbian.h | 2 - qmake/generators/symbian/symmake.cpp | 3 + qmake/generators/symbian/symmake_abld.cpp | 3 + qmake/generators/symbian/symmake_sbsv2.cpp | 3 + qmake/project.cpp | 5 +- qmake/qmake.pri | 6 +- tools/shared/symbian/epocroot.cpp | 230 +++++++++++++++++++++ tools/shared/symbian/epocroot.h | 67 ++++++ 14 files changed, 337 insertions(+), 151 deletions(-) delete mode 100644 qmake/generators/symbian/epocroot.h create mode 100644 tools/shared/symbian/epocroot.cpp create mode 100644 tools/shared/symbian/epocroot.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index e343803..5469134 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -11,7 +11,8 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o + registry.o \ + epocroot.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -22,6 +23,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ registry.o \ + epocroot.o \ $(QTOBJS) @@ -35,6 +37,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ + $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -288,6 +291,9 @@ initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp @@ -296,6 +302,7 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp + #default rules .cpp.o: $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 3cd180c..48d84b7 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -78,6 +78,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ registry.obj \ + epocroot.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -202,6 +203,7 @@ clean:: -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj -del registry.obj + -del epocroot.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -404,6 +406,9 @@ initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initproje registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.obj: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ebc7fe2..169de3c 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -40,6 +40,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ + epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -283,6 +284,9 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 1d55da2..98237e7 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -40,6 +40,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ + epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -282,6 +283,9 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/symbian/epocroot.h b/qmake/generators/symbian/epocroot.h deleted file mode 100644 index be26438..0000000 --- a/qmake/generators/symbian/epocroot.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EPOCROOT_H -#define EPOCROOT_H - -#include - -// Implementation of epocRoot method is in initprojectdeploy_symbian.cpp -// Defined in separate header for inclusion clarity -extern QString epocRoot(); - -#endif // EPOCROOT_H diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 5fbff58..2a22305 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -46,105 +46,15 @@ #include #include +// Included from tools/shared +#include + #define SYSBIN_DIR "\\sys\\bin" #define SUFFIX_DLL "dll" #define SUFFIX_EXE "exe" #define SUFFIX_QTPLUGIN "qtplugin" -static void fixEpocRootStr(QString& path) -{ - path.replace("\\", "/"); - - if (path.size() > 1 && path[1] == QChar(':')) { - path = path.mid(2); - } - - if (!path.size() || path[path.size()-1] != QChar('/')) { - path += QChar('/'); - } -} - -#define SYMBIAN_SDKS_KEY "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs" - -static QString epocRootStr; - -QString epocRoot() -{ - if (!epocRootStr.isEmpty()) { - return epocRootStr; - } - - // First, check the env variable - epocRootStr = qgetenv("EPOCROOT"); - - if (epocRootStr.isEmpty()) { - // No EPOCROOT set, check the default device - // First check EPOCDEVICE env variable - QString defaultDevice = qgetenv("EPOCDEVICE"); - - // Check the windows registry via QSettings for devices.xml path - QSettings settings(SYMBIAN_SDKS_KEY, QSettings::NativeFormat); - QString devicesXmlPath = settings.value("CommonPath").toString(); - - if (!devicesXmlPath.isEmpty()) { - // Parse xml for correct device - devicesXmlPath += "/devices.xml"; - QFile devicesFile(devicesXmlPath); - if (devicesFile.open(QIODevice::ReadOnly)) { - QXmlStreamReader xml(&devicesFile); - while (!xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "devices") { - if (xml.attributes().value("version") == "1.0") { - // Look for correct device - while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "device") { - if ((defaultDevice.isEmpty() && xml.attributes().value("default") == "yes") || - (!defaultDevice.isEmpty() && (xml.attributes().value("id").toString() + QString(":") + xml.attributes().value("name").toString()) == defaultDevice)) { - // Found the correct device - while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "epocroot") { - epocRootStr = xml.readElementText(); - fixEpocRootStr(epocRootStr); - return epocRootStr; - } - } - xml.raiseError("No epocroot element found"); - } - } - } - } else { - xml.raiseError("Invalid 'devices' element version"); - } - } - } - if (xml.hasError()) { - fprintf(stderr, "ERROR: \"%s\" when parsing devices.xml\n", qPrintable(xml.errorString())); - } - } else { - fprintf(stderr, "Could not open devices.xml (%s)\n", qPrintable(devicesXmlPath)); - } - } else { - fprintf(stderr, "Could not retrieve " SYMBIAN_SDKS_KEY " setting\n"); - } - - fprintf(stderr, "Failed to determine epoc root.\n"); - if (!defaultDevice.isEmpty()) - fprintf(stderr, "The device indicated by EPOCDEVICE environment variable (%s) could not be found.\n", qPrintable(defaultDevice)); - fprintf(stderr, "Either set EPOCROOT or EPOCDEVICE environment variable to a valid value, or provide a default Symbian device.\n"); - - // No valid device found; set epocroot to "/" - epocRootStr = QLatin1String("/"); - } - - fixEpocRootStr(epocRootStr); - return epocRootStr; -} - - static bool isPlugin(const QFileInfo& info, const QString& devicePath) { // Libraries are plugins if deployment path is something else than diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index e23e6a9..b409225 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -50,8 +50,6 @@ #include #include -#include "epocroot.h" - #define PLUGIN_STUB_DIR "qmakepluginstubs" struct CopyItem diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 2055f81..a712434 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -49,6 +49,9 @@ #include #include +// Included from tools/shared +#include + #define RESOURCE_DIRECTORY_MMP "/resource/apps" #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 033bcbe..6c62412 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -48,6 +48,9 @@ #include #include +// Included from tools/shared +#include + #define DO_NOTHING_TARGET "do_nothing" #define CREATE_TEMPS_TARGET "create_temps" #define EXTENSION_CLEAN "extension_clean" diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index e081b19..8accfce 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -48,6 +48,9 @@ #include #include +// Included from tools/shared +#include + SymbianSbsv2MakefileGenerator::SymbianSbsv2MakefileGenerator() : SymbianMakefileGenerator() { } SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { } diff --git a/qmake/project.cpp b/qmake/project.cpp index 4ce8ba4..e4ef7dd 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -44,8 +44,6 @@ #include "option.h" #include "cachekeys.h" -#include "epocroot.h" - #include #include #include @@ -64,6 +62,9 @@ #include #include +// Included from tools/shared +#include + #ifdef Q_OS_WIN32 #define QT_POPEN _popen #define QT_PCLOSE _pclose diff --git a/qmake/qmake.pri b/qmake/qmake.pri index a2ffe15..05debe6 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -18,7 +18,8 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ generators/symbian/initprojectdeploy_symbian.cpp \ - windows/registry.cpp + windows/registry.cpp \ + symbian/epocroot.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -31,7 +32,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ generators/symbian/initprojectdeploy_symbian.h \ - windows/registry.h + windows/registry.h \ + symbian/epocroot.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/tools/shared/symbian/epocroot.cpp b/tools/shared/symbian/epocroot.cpp new file mode 100644 index 0000000..071477d --- /dev/null +++ b/tools/shared/symbian/epocroot.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +#include "epocroot.h" +#include "../windows/registry.h" + +// Registry key under which the location of the Symbian devices.xml file is +// stored. +// Note that, on 64-bit machines, this key is located under the 32-bit +// compatibility key: +// HKEY_LOCAL_MACHINE\Software\Wow6432Node +#define SYMBIAN_SDKS_REG_SUBKEY "Software\\Symbian\\EPOC SDKs\\CommonPath" + +#ifdef Q_OS_WIN32 +# define SYMBIAN_SDKS_REG_HANDLE HKEY_LOCAL_MACHINE +#else +# define SYMBIAN_SDKS_REG_HANDLE 0 +#endif + +// Value which is populated and returned by the epocRoot() function. +// Stored as a static value in order to avoid unnecessary re-evaluation. +static QString epocRootValue; + +#ifdef QT_BUILD_QMAKE +std::ostream &operator<<(std::ostream &s, const QString &val) { + s << val.toLocal8Bit().data(); + return s; +} +#else +// Operator implemented in configureapp.cpp +std::ostream &operator<<(std::ostream &s, const QString &val); +#endif + +QString getDevicesXmlPath() + { + // Note that the following call will return a null string on platforms other + // than Windows. If support is required on other platforms for devices.xml, + // an alternative mechanism for retrieving the location of this file will + // be required. + return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY); + } + +/** + * Checks whether epocRootValue points to an existent directory. + * If not, epocRootValue is set to an empty string and an error message is printed. + */ +void checkEpocRootExists(const QString &source) +{ + if (!epocRootValue.isEmpty()) { + QDir dir(epocRootValue); + if (!dir.exists()) { + std::cerr << "Warning: " << source << " is set to an invalid path: " << epocRootValue << std::endl; + epocRootValue = QString(); + } + } +} + +/** + * Translate path from Windows to Qt format. + */ +static void fixEpocRoot(QString &path) +{ + path.replace("\\", "/"); + + if (path.size() > 1 && path[1] == QChar(':')) { + path = path.mid(2); + } + + if (!path.size() || path[path.size()-1] != QChar('/')) { + path += QChar('/'); + } +} + +/** + * Determine the epoc root for the currently active SDK. + */ +QString epocRoot() +{ + if (epocRootValue.isEmpty()) { + // 1. If environment variable EPOCROOT is set and points to an existent + // directory, this is returned. + epocRootValue = qgetenv("EPOCROOT"); + checkEpocRootExists("EPOCROOT"); + + if (epocRootValue.isEmpty()) { + // 2. The location of devices.xml is specified by a registry key. If this + // file exists, it is parsed. + QString devicesXmlPath = getDevicesXmlPath(); + if (devicesXmlPath.isEmpty()) { + std::cerr << "Error: Symbian SDK registry key not found" << std::endl; + } else { + devicesXmlPath += "/devices.xml"; + QFile devicesFile(devicesXmlPath); + if (devicesFile.open(QIODevice::ReadOnly)) { + + // 3. If the EPOCDEVICE environment variable is set and a corresponding + // entry is found in devices.xml, and its epocroot value points to an + // existent directory, it is returned. + // 4. If a device element marked as default is found in devices.xml and its + // epocroot value points to an existent directory, this is returned. + + const QString epocDeviceValue = qgetenv("EPOCDEVICE"); + bool epocDeviceFound = false; + + QXmlStreamReader xml(&devicesFile); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "devices") { + if (xml.attributes().value("version") == "1.0") { + while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "device") { + const bool isDefault = xml.attributes().value("default") == "yes"; + const QString id = xml.attributes().value("id").toString(); + const QString name = xml.attributes().value("name").toString(); + const bool epocDeviceMatch = (id + ":" + name) == epocDeviceValue; + epocDeviceFound |= epocDeviceMatch; + + if((epocDeviceValue.isEmpty() && isDefault) || epocDeviceMatch) { + // Found a matching device + while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "epocroot") { + epocRootValue = xml.readElementText(); + const QString deviceSource = epocDeviceValue.isEmpty() + ? "default device" + : "EPOCDEVICE (" + epocDeviceValue + ")"; + checkEpocRootExists(deviceSource); + } + } + + if (epocRootValue.isEmpty()) + xml.raiseError("No epocroot element found"); + } + } + } + } else { + xml.raiseError("Invalid 'devices' element version"); + } + } + } + if (xml.hasError()) { + std::cerr << "Error: \"" << xml.errorString() << "\" when parsing devices.xml" << std::endl; + } else { + if (epocRootValue.isEmpty()) { + if (!epocDeviceValue.isEmpty()) { + if (epocDeviceFound) { + std::cerr << "Error: missing or invalid epocroot attribute " + << "in device '" << epocDeviceValue << "'"; + } else { + std::cerr << "Error: no device matching EPOCDEVICE (" + << epocDeviceValue << ")"; + } + } else { + if (epocDeviceFound) { + std::cerr << "Error: missing or invalid epocroot attribute " + << "in default device"; + } else { + std::cerr << "Error: no default device"; + } + } + std::cerr << " found in devices.xml file." << std::endl; + } + } + } else { + std::cerr << "Error: could not open file " << devicesXmlPath << std::endl; + } + } + } + + if (epocRootValue.isEmpty()) { + // 5. An empty string is returned. + std::cerr << "Error: failed to find epoc root" << std::endl + << "Either" << std::endl + << " 1. Set EPOCROOT environment variable to a valid value" << std::endl + << " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY + " registry key is set, and then" << std::endl + << " a. Set EPOCDEVICE environment variable to a valid device" << std::endl + << " or b. Specify a default device in the devices.xml file." << std::endl; + } else { + fixEpocRoot(epocRootValue); + } + } + + return epocRootValue; +} + diff --git a/tools/shared/symbian/epocroot.h b/tools/shared/symbian/epocroot.h new file mode 100644 index 0000000..9846485 --- /dev/null +++ b/tools/shared/symbian/epocroot.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIAN_EPOCROOT_H +#define SYMBIAN_EPOCROOT_H + +#include + +/** + * Determine the epoc root for the currently active SDK. + * + * The algorithm used is as follows: + * 1. If environment variable EPOCROOT is set and points to an existent + * directory, this is returned. + * 2. The location of devices.xml is specified by a registry key. If this + * file exists, it is parsed. + * 3. If the EPOCDEVICE environment variable is set and a corresponding + * entry is found in devices.xml, and its epocroot value points to an + * existent directory, it is returned. + * 4. If a device element marked as default is found in devices.xml and its + * epocroot value points to an existent directory, this is returned. + * 5. An empty string is returned. + * + * Any return value other than the empty string therefore is guaranteed to + * point to an existent directory. + */ +QString epocRoot(); + +#endif // EPOCROOT_H -- cgit v0.12 From ea34fbde76a0407dc4a9bb9f4a3140c4764ca6ba Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 15:16:20 +0000 Subject: Removed duplicated implementation of readRegistryKeys from configure Configure now shares - at the source level - a single implementation of this function with qmake. Reviewed-by: Miikka Heikkinen --- tools/configure/configure.pro | 7 ++- tools/configure/environment.cpp | 121 +--------------------------------------- tools/configure/environment.h | 3 - 3 files changed, 6 insertions(+), 125 deletions(-) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 243183c..ca2ba84 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -27,6 +27,7 @@ INCPATH += $$QT_SOURCE_TREE/src/corelib/arch/generic \ $$QT_SOURCE_TREE/src/corelib/global \ $$QT_BUILD_TREE/include \ $$QT_BUILD_TREE/include/QtCore \ + $$QT_BUILD_TREE/tools/shared HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/tools/qbytearray.h \ @@ -58,7 +59,8 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/tools/qstring.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstringmatcher.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qunicodetables_p.h + $$QT_SOURCE_TREE/src/corelib/tools/qunicodetables_p.h \ + $$QT_SOURCE_TREE/tools/shared/windows/registry.h SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ @@ -102,7 +104,8 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qpoint.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qrect.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \ - $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp + $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \ + $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp win32:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index af6f9e5..da86f5d 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -60,6 +60,7 @@ using namespace std; #include #endif +#include // from tools/shared QT_BEGIN_NAMESPACE @@ -97,126 +98,6 @@ CompilerInfo *Environment::compilerInfo(Compiler compiler) } /*! - Returns the path part of a registry key. - Ei. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" -*/ -QString Environment::keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -/*! - Returns the name part of a registry key. - Ei. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "ProductDir" -*/ -QString Environment::keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == "Default" || res == ".") - res = ""; - return res; -} - -/*! - Returns a registry keys value in string form. - If the registry key does not exist, or cannot be accessed, a - QString() is returned. -*/ -QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) -{ -#ifndef Q_OS_WIN32 - return QString(); -#else - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = 0; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - QString result; - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(", "); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); - break; - } - - RegCloseKey(handle); - return result; -#endif -} - -/*! Returns the qmakespec for the compiler detected on the system. */ QString Environment::detectQMakeSpec() diff --git a/tools/configure/environment.h b/tools/configure/environment.h index 2d0eafd..549dcfa 100644 --- a/tools/configure/environment.h +++ b/tools/configure/environment.h @@ -75,9 +75,6 @@ private: static Compiler detectedCompiler; static CompilerInfo *compilerInfo(Compiler compiler); - static QString keyPath(const QString &rKey); - static QString keyName(const QString &rKey); - static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey); }; -- cgit v0.12 From 35f7b0803ea9f43981370aff0da4f4d06c248396 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 20:30:24 +0000 Subject: Added implementation of epocRoot() function to configure Exposing epocRoot() to the configure application allows it to determine the location of the currently active Symbian SDK, so that support for optional SDK features can be checked. Reviewed-by: Miikka Heikkinen --- src/corelib/xml/qxmlstream_p.h | 2 +- tools/configure/configure.pro | 10 ++++++++-- tools/configure/environment.cpp | 7 +++++++ tools/configure/environment.h | 2 ++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 6b911d2..ac421cf 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -54,7 +54,7 @@ #ifndef QXMLSTREAM_P_H #define QXMLSTREAM_P_H -#if defined(Q_OS_VXWORKS) && defined(ERROR) +#if defined(ERROR) # undef ERROR #endif diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index ca2ba84..91de7c2 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -3,8 +3,8 @@ DESTDIR = ../.. CONFIG += console flat CONFIG -= moc qt -DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE - +DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE +DEFINES += QT_BOOTSTRAPPED win32 : LIBS += -lole32 -ladvapi32 win32-msvc.net | win32-msvc2* : QMAKE_CXXFLAGS += /EHsc @@ -60,6 +60,9 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstringmatcher.h \ $$QT_SOURCE_TREE/src/corelib/tools/qunicodetables_p.h \ + $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.h \ + $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils_p.h \ + $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.h \ $$QT_SOURCE_TREE/tools/shared/windows/registry.h @@ -105,6 +108,9 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qrect.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \ $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \ + $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.cpp \ + $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils.cpp \ + $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp win32:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index da86f5d..e93f9a0 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -60,6 +60,7 @@ using namespace std; #include #endif +#include // from tools/shared #include // from tools/shared QT_BEGIN_NAMESPACE @@ -460,4 +461,10 @@ bool Environment::rmdir(const QString &name) return result; } +QString Environment::symbianEpocRoot() +{ + // Call function defined in tools/shared/symbian/epocroot.h + return ::epocRoot(); +} + QT_END_NAMESPACE diff --git a/tools/configure/environment.h b/tools/configure/environment.h index 549dcfa..b1cbe3a 100644 --- a/tools/configure/environment.h +++ b/tools/configure/environment.h @@ -71,6 +71,8 @@ public: static bool cpdir(const QString &srcDir, const QString &destDir); static bool rmdir(const QString &name); + static QString symbianEpocRoot(); + private: static Compiler detectedCompiler; -- cgit v0.12 From b76e3e5f4e9cad5c2e7331031e5a44868616105e Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 20:44:10 +0000 Subject: Modified configure to detect SDK support for Symbian audio backend This version of configure.exe was compiled with MSVC 9.0. Reviewed-by: Miikka Heikkinen --- configure.exe | Bin 1179136 -> 1008128 bytes tools/configure/configureapp.cpp | 50 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/configure.exe b/configure.exe index 09f4ef2..9974236 100755 Binary files a/configure.exe and b/configure.exe differ diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9e0cb70..d521276 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -247,7 +247,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "PHONON" ] = "auto"; dictionary[ "PHONON_BACKEND" ] = "yes"; dictionary[ "MULTIMEDIA" ] = "yes"; - dictionary[ "AUDIO_BACKEND" ] = "yes"; + dictionary[ "AUDIO_BACKEND" ] = "auto"; dictionary[ "DIRECTSHOW" ] = "no"; dictionary[ "WEBKIT" ] = "auto"; dictionary[ "DECLARATIVE" ] = "auto"; @@ -2065,6 +2065,52 @@ bool Configure::checkAvailability(const QString &part) available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++"); } else if (part == "DECLARATIVE") { available = QFile::exists(sourcePath + "/src/declarative/qml/qmlcomponent.h"); + } else if (part == "AUDIO_BACKEND") { + available = true; + if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { + QString epocRoot = Environment::symbianEpocRoot(); + const QDir epocRootDir(epocRoot); + if (epocRootDir.exists()) { + QStringList paths; + paths << "epoc32/release/armv5/lib/mmfdevsound.dso" + << "epoc32/release/armv5/lib/mmfdevsound.lib" + << "epoc32/release/winscw/udeb/mmfdevsound.dll" + << "epoc32/release/winscw/udeb/mmfdevsound.lib" + << "epoc32/include/mmf/server/sounddevice.h"; + + QStringList::iterator i = paths.begin(); + while (i != paths.end()) { + const QString &path = epocRoot + *i; + if (QFile::exists(path)) + i = paths.erase(i); + else + ++i; + } + + available = (paths.size() == 0); + if (!available) { + if (epocRoot.isNull() || epocRoot == "") + epocRoot = ""; + cout << endl + << "The QtMultimedia audio backend will not be built because required" << endl + << "support for CMMFDevSound was not found in the SDK." << endl + << "The SDK which was examined was located at the following path:" << endl + << " " << epocRoot << endl + << "The following required files were missing from the SDK:" << endl; + QString path; + foreach (path, paths) + cout << " " << path << endl; + cout << endl; + } + } else { + cout << endl + << "The SDK root was determined to be '" << epocRoot << "'." << endl + << "This directory was not found, so the SDK could not be checked for" << endl + << "CMMFDevSound support. The QtMultimedia audio backend will therefore" << endl + << "not be built." << endl << endl; + available = false; + } + } } return available; @@ -2153,6 +2199,8 @@ void Configure::autoDetection() dictionary["WEBKIT"] = checkAvailability("WEBKIT") ? "yes" : "no"; if (dictionary["DECLARATIVE"] == "auto") dictionary["DECLARATIVE"] = checkAvailability("DECLARATIVE") ? "yes" : "no"; + if (dictionary["AUDIO_BACKEND"] == "auto") + dictionary["AUDIO_BACKEND"] = checkAvailability("AUDIO_BACKEND") ? "yes" : "no"; // Qt/WinCE remote test application if (dictionary["CETEST"] == "auto") -- cgit v0.12 From 28610950d2efb0b543ede40512f6172c37c78698 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 18 Feb 2010 14:10:03 +0000 Subject: Symbian backend for QtMultimedia audio Task-number: QT-567 --- src/plugins/audio/audio.pro | 8 +- src/plugins/audio/symbian/main.cpp | 121 ++++ src/plugins/audio/symbian/symbian.pro | 31 + src/plugins/audio/symbian/symbianaudio.h | 76 +++ .../audio/symbian/symbianaudiodeviceinfo.cpp | 191 ++++++ src/plugins/audio/symbian/symbianaudiodeviceinfo.h | 94 +++ src/plugins/audio/symbian/symbianaudioinput.cpp | 595 ++++++++++++++++++ src/plugins/audio/symbian/symbianaudioinput.h | 177 ++++++ src/plugins/audio/symbian/symbianaudiooutput.cpp | 697 +++++++++++++++++++++ src/plugins/audio/symbian/symbianaudiooutput.h | 199 ++++++ src/plugins/audio/symbian/symbianaudioutils.cpp | 395 ++++++++++++ src/plugins/audio/symbian/symbianaudioutils.h | 125 ++++ src/s60installs/qt.iby | 6 + src/s60installs/s60installs.pro | 6 + 14 files changed, 2720 insertions(+), 1 deletion(-) create mode 100644 src/plugins/audio/symbian/main.cpp create mode 100644 src/plugins/audio/symbian/symbian.pro create mode 100644 src/plugins/audio/symbian/symbianaudio.h create mode 100644 src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp create mode 100644 src/plugins/audio/symbian/symbianaudiodeviceinfo.h create mode 100644 src/plugins/audio/symbian/symbianaudioinput.cpp create mode 100644 src/plugins/audio/symbian/symbianaudioinput.h create mode 100644 src/plugins/audio/symbian/symbianaudiooutput.cpp create mode 100644 src/plugins/audio/symbian/symbianaudiooutput.h create mode 100644 src/plugins/audio/symbian/symbianaudioutils.cpp create mode 100644 src/plugins/audio/symbian/symbianaudioutils.h diff --git a/src/plugins/audio/audio.pro b/src/plugins/audio/audio.pro index e93b369..5f75a8d 100644 --- a/src/plugins/audio/audio.pro +++ b/src/plugins/audio/audio.pro @@ -1,3 +1,9 @@ TEMPLATE = subdirs +SUBDIRS = + +contains(QT_CONFIG, audio-backend) { + symbian { + SUBDIRS += symbian + } +} -#SUBDIRS += ossaudio diff --git a/src/plugins/audio/symbian/main.cpp b/src/plugins/audio/symbian/main.cpp new file mode 100644 index 0000000..377944b --- /dev/null +++ b/src/plugins/audio/symbian/main.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "symbianaudiodeviceinfo.h" +#include "symbianaudioinput.h" +#include "symbianaudiooutput.h" + +QT_BEGIN_NAMESPACE + +class SymbianAudioPlugin : public QAudioEnginePlugin +{ +public: + SymbianAudioPlugin(QObject *parent = 0); + ~SymbianAudioPlugin(); + + QStringList keys() const; + + QList availableDevices(QAudio::Mode) const; + QAbstractAudioInput* createInput(const QByteArray& device, + const QAudioFormat& format = QAudioFormat()); + QAbstractAudioOutput* createOutput(const QByteArray& device, + const QAudioFormat& format = QAudioFormat()); + QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, + QAudio::Mode mode); +}; + +SymbianAudioPlugin::SymbianAudioPlugin(QObject *parent) + : QAudioEnginePlugin(parent) +{ + +} + +SymbianAudioPlugin::~SymbianAudioPlugin() +{ + +} + +QStringList SymbianAudioPlugin::keys() const +{ + QStringList keys(QLatin1String("default")); + keys << QLatin1String("default"); + return keys; +} + +QList SymbianAudioPlugin::availableDevices(QAudio::Mode mode) const +{ + Q_UNUSED(mode) + QList devices; + devices.append("default"); + return devices; +} + +QAbstractAudioInput* SymbianAudioPlugin::createInput( + const QByteArray &device, const QAudioFormat &format) +{ + return new SymbianAudioInput(device, format); +} + +QAbstractAudioOutput* SymbianAudioPlugin::createOutput( + const QByteArray &device, const QAudioFormat &format) +{ + return new SymbianAudioOutput(device, format); +} + +QAbstractAudioDeviceInfo* SymbianAudioPlugin::createDeviceInfo( + const QByteArray& device, QAudio::Mode mode) +{ + return new SymbianAudioDeviceInfo(device, mode); +} + +Q_EXPORT_STATIC_PLUGIN(SymbianAudioPlugin) +Q_EXPORT_PLUGIN2(qaudio, SymbianAudioPlugin) + +QT_END_NAMESPACE + diff --git a/src/plugins/audio/symbian/symbian.pro b/src/plugins/audio/symbian/symbian.pro new file mode 100644 index 0000000..7355daa --- /dev/null +++ b/src/plugins/audio/symbian/symbian.pro @@ -0,0 +1,31 @@ +QT += multimedia +TARGET = qaudio + +# Paths to DevSound headers +INCLUDEPATH += /epoc32/include/mmf/common +INCLUDEPATH += /epoc32/include/mmf/server + +HEADERS += \ + symbianaudio.h \ + symbianaudiodeviceinfo.h \ + symbianaudioinput.h \ + symbianaudiooutput.h \ + symbianaudioutils.h + +SOURCES += \ + main.cpp \ + symbianaudiodeviceinfo.cpp \ + symbianaudioinput.cpp \ + symbianaudiooutput.cpp \ + symbianaudioutils.cpp + +LIBS += -lmmfdevsound + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/audio +target.path = $$[QT_INSTALL_PLUGINS]/audio +INSTALLS += target + +include(../../qpluginbase.pri) + +TARGET.UID3 = 0x2001E630 + diff --git a/src/plugins/audio/symbian/symbianaudio.h b/src/plugins/audio/symbian/symbianaudio.h new file mode 100644 index 0000000..527aa55 --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudio.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANAUDIO_H +#define SYMBIANAUDIO_H + +#include + +QT_BEGIN_NAMESPACE + +namespace SymbianAudio { + +/** + * Default values used by audio input and output classes, when underlying + * DevSound instance has not yet been created. + */ + +const int DefaultBufferSize = 4096; // bytes +const int DefaultNotifyInterval = 1000; // ms + +/** + * Enumeration used to track state of internal DevSound instances. + * Values are translated to the corresponding QAudio::State values by + * SymbianAudio::Utils::stateNativeToQt. + */ +enum State { + ClosedState + , InitializingState + , ActiveState + , IdleState + , SuspendedState +}; + +} // namespace SymbianAudio + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp new file mode 100644 index 0000000..b8d59de --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianaudiodeviceinfo.h" +#include "symbianaudioutils.h" + +QT_BEGIN_NAMESPACE + +SymbianAudioDeviceInfo::SymbianAudioDeviceInfo(QByteArray device, + QAudio::Mode mode) + : m_deviceName(device) + , m_mode(mode) + , m_updated(false) +{ + QT_TRAP_THROWING(m_devsound.reset(CMMFDevSound::NewL())); +} + +SymbianAudioDeviceInfo::~SymbianAudioDeviceInfo() +{ + +} + +QAudioFormat SymbianAudioDeviceInfo::preferredFormat() const +{ + QAudioFormat format; + switch (m_mode) { + case QAudio::AudioOutput: + format.setFrequency(44100); + format.setChannels(2); + format.setSampleSize(16); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + format.setCodec(QLatin1String("audio/pcm")); + break; + + case QAudio::AudioInput: + format.setFrequency(8000); + format.setChannels(1); + format.setSampleSize(16); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + format.setCodec(QLatin1String("audio/pcm")); + break; + + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid mode"); + } + + if (!isFormatSupported(format)) { + if (m_frequencies.size()) + format.setFrequency(m_frequencies[0]); + if (m_channels.size()) + format.setChannels(m_channels[0]); + if (m_sampleSizes.size()) + format.setSampleSize(m_sampleSizes[0]); + if (m_byteOrders.size()) + format.setByteOrder(m_byteOrders[0]); + if (m_sampleTypes.size()) + format.setSampleType(m_sampleTypes[0]); + } + + return format; +} + +bool SymbianAudioDeviceInfo::isFormatSupported( + const QAudioFormat &format) const +{ + getSupportedFormats(); + const bool supported = + m_codecs.contains(format.codec()) + && m_frequencies.contains(format.frequency()) + && m_channels.contains(format.channels()) + && m_sampleSizes.contains(format.sampleSize()) + && m_byteOrders.contains(format.byteOrder()) + && m_sampleTypes.contains(format.sampleType()); + + return supported; +} + +QAudioFormat SymbianAudioDeviceInfo::nearestFormat(const QAudioFormat &format) const +{ + if (isFormatSupported(format)) + return format; + else + return preferredFormat(); +} + +QString SymbianAudioDeviceInfo::deviceName() const +{ + return m_deviceName; +} + +QStringList SymbianAudioDeviceInfo::codecList() +{ + getSupportedFormats(); + return m_codecs; +} + +QList SymbianAudioDeviceInfo::frequencyList() +{ + getSupportedFormats(); + return m_frequencies; +} + +QList SymbianAudioDeviceInfo::channelsList() +{ + getSupportedFormats(); + return m_channels; +} + +QList SymbianAudioDeviceInfo::sampleSizeList() +{ + getSupportedFormats(); + return m_sampleSizes; +} + +QList SymbianAudioDeviceInfo::byteOrderList() +{ + getSupportedFormats(); + return m_byteOrders; +} + +QList SymbianAudioDeviceInfo::sampleTypeList() +{ + getSupportedFormats(); + return m_sampleTypes; +} + +QList SymbianAudioDeviceInfo::deviceList(QAudio::Mode mode) +{ + Q_UNUSED(mode) + QList devices; + devices.append("default"); + return devices; +} + +void SymbianAudioDeviceInfo::getSupportedFormats() const +{ + if (!m_updated) { + QScopedPointer caps( + new SymbianAudio::DevSoundCapabilities(*m_devsound, m_mode)); + + SymbianAudio::Utils::capabilitiesNativeToQt(*caps, + m_frequencies, m_channels, m_sampleSizes, + m_byteOrders, m_sampleTypes); + + m_codecs.append(QLatin1String("audio/pcm")); + + m_updated = true; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.h b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h new file mode 100644 index 0000000..1df6afb --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANAUDIODEVICEINFO_H +#define SYMBIANAUDIODEVICEINFO_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class SymbianAudioDeviceInfo + : public QAbstractAudioDeviceInfo +{ + Q_OBJECT + +public: + SymbianAudioDeviceInfo(QByteArray device, QAudio::Mode mode); + ~SymbianAudioDeviceInfo(); + + // QAbstractAudioDeviceInfo + QAudioFormat preferredFormat() const; + bool isFormatSupported(const QAudioFormat &format) const; + QAudioFormat nearestFormat(const QAudioFormat &format) const; + QString deviceName() const; + QStringList codecList(); + QList frequencyList(); + QList channelsList(); + QList sampleSizeList(); + QList byteOrderList(); + QList sampleTypeList(); + QList deviceList(QAudio::Mode); + +private: + void getSupportedFormats() const; + +private: + QScopedPointer m_devsound; + + QString m_deviceName; + QAudio::Mode m_mode; + + // Mutable to allow lazy initialization when called from const-qualified + // public functions (isFormatSupported, nearestFormat) + mutable bool m_updated; + mutable QStringList m_codecs; + mutable QList m_frequencies; + mutable QList m_channels; + mutable QList m_sampleSizes; + mutable QList m_byteOrders; + mutable QList m_sampleTypes; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/audio/symbian/symbianaudioinput.cpp b/src/plugins/audio/symbian/symbianaudioinput.cpp new file mode 100644 index 0000000..c1a6299 --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudioinput.cpp @@ -0,0 +1,595 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianaudioinput.h" +#include "symbianaudioutils.h" + +QT_BEGIN_NAMESPACE + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +const int PushInterval = 50; // ms + + +//----------------------------------------------------------------------------- +// Private class +//----------------------------------------------------------------------------- + +SymbianAudioInputPrivate::SymbianAudioInputPrivate( + SymbianAudioInput *audioDevice) + : m_audioDevice(audioDevice) +{ + +} + +SymbianAudioInputPrivate::~SymbianAudioInputPrivate() +{ + +} + +qint64 SymbianAudioInputPrivate::readData(char *data, qint64 len) +{ + qint64 totalRead = 0; + + if (m_audioDevice->state() == QAudio::ActiveState || + m_audioDevice->state() == QAudio::IdleState) { + + while (totalRead < len) { + const qint64 read = m_audioDevice->read(data + totalRead, + len - totalRead); + if (read > 0) + totalRead += read; + else + break; + } + } + + return totalRead; +} + +qint64 SymbianAudioInputPrivate::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data) + Q_UNUSED(len) + return 0; +} + +void SymbianAudioInputPrivate::dataReady() +{ + emit readyRead(); +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +SymbianAudioInput::SymbianAudioInput(const QByteArray &device, + const QAudioFormat &format) + : m_device(device) + , m_format(format) + , m_clientBufferSize(SymbianAudio::DefaultBufferSize) + , m_notifyInterval(SymbianAudio::DefaultNotifyInterval) + , m_notifyTimer(new QTimer(this)) + , m_error(QAudio::NoError) + , m_internalState(SymbianAudio::ClosedState) + , m_externalState(QAudio::StoppedState) + , m_pullMode(false) + , m_sink(0) + , m_pullTimer(new QTimer(this)) + , m_devSoundBuffer(0) + , m_devSoundBufferSize(0) + , m_totalBytesReady(0) + , m_devSoundBufferPos(0) + , m_totalSamplesRecorded(0) +{ + connect(m_notifyTimer.data(), SIGNAL(timeout()), this, SIGNAL(notify())); + + SymbianAudio::Utils::formatQtToNative(m_format, m_nativeFourCC, + m_nativeFormat); + + m_pullTimer->setInterval(PushInterval); + connect(m_pullTimer.data(), SIGNAL(timeout()), this, SLOT(pullData())); +} + +SymbianAudioInput::~SymbianAudioInput() +{ + close(); +} + +QIODevice* SymbianAudioInput::start(QIODevice *device) +{ + stop(); + + open(); + if (SymbianAudio::ClosedState != m_internalState) { + if (device) { + m_pullMode = true; + m_sink = device; + } else { + m_sink = new SymbianAudioInputPrivate(this); + m_sink->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + } + + m_elapsed.restart(); + } + + return m_sink; +} + +void SymbianAudioInput::stop() +{ + close(); +} + +void SymbianAudioInput::reset() +{ + m_totalSamplesRecorded += getSamplesRecorded(); + m_devSound->Stop(); + startRecording(); +} + +void SymbianAudioInput::suspend() +{ + if (SymbianAudio::ActiveState == m_internalState + || SymbianAudio::IdleState == m_internalState) { + m_notifyTimer->stop(); + m_pullTimer->stop(); + m_devSound->Pause(); + const qint64 samplesRecorded = getSamplesRecorded(); + m_totalSamplesRecorded += samplesRecorded; + + if (m_devSoundBuffer) { + m_devSoundBufferQ.append(m_devSoundBuffer); + m_devSoundBuffer = 0; + } + + setState(SymbianAudio::SuspendedState); + } +} + +void SymbianAudioInput::resume() +{ + if (SymbianAudio::SuspendedState == m_internalState) + startDataTransfer(); +} + +int SymbianAudioInput::bytesReady() const +{ + Q_ASSERT(m_devSoundBufferPos <= m_totalBytesReady); + return m_totalBytesReady - m_devSoundBufferPos; +} + +int SymbianAudioInput::periodSize() const +{ + return bufferSize(); +} + +void SymbianAudioInput::setBufferSize(int value) +{ + // Note that DevSound does not allow its client to specify the buffer size. + // This functionality is available via custom interfaces, but since these + // cannot be guaranteed to work across all DevSound implementations, we + // do not use them here. + // In order to comply with the expected bevahiour of QAudioInput, we store + // the value and return it from bufferSize(), but the underlying DevSound + // buffer size remains unchanged. + if (value > 0) + m_clientBufferSize = value; +} + +int SymbianAudioInput::bufferSize() const +{ + return m_devSoundBufferSize ? m_devSoundBufferSize : m_clientBufferSize; +} + +void SymbianAudioInput::setNotifyInterval(int ms) +{ + if (ms > 0) { + const int oldNotifyInterval = m_notifyInterval; + m_notifyInterval = ms; + if (m_notifyTimer->isActive() && ms != oldNotifyInterval) + m_notifyTimer->start(m_notifyInterval); + } +} + +int SymbianAudioInput::notifyInterval() const +{ + return m_notifyInterval; +} + +qint64 SymbianAudioInput::processedUSecs() const +{ + int samplesPlayed = 0; + if (m_devSound && SymbianAudio::SuspendedState != m_internalState) + samplesPlayed = getSamplesRecorded(); + + // Protect against division by zero + Q_ASSERT_X(m_format.frequency() > 0, Q_FUNC_INFO, "Invalid frequency"); + + const qint64 result = qint64(1000000) * + (samplesPlayed + m_totalSamplesRecorded) + / m_format.frequency(); + + return result; +} + +qint64 SymbianAudioInput::elapsedUSecs() const +{ + const qint64 result = (QAudio::StoppedState == state()) ? + 0 : m_elapsed.elapsed() * 1000; + return result; +} + +QAudio::Error SymbianAudioInput::error() const +{ + return m_error; +} + +QAudio::State SymbianAudioInput::state() const +{ + return m_externalState; +} + +QAudioFormat SymbianAudioInput::format() const +{ + return m_format; +} + +//----------------------------------------------------------------------------- +// MDevSoundObserver implementation +//----------------------------------------------------------------------------- + +void SymbianAudioInput::InitializeComplete(TInt aError) +{ + Q_ASSERT_X(SymbianAudio::InitializingState == m_internalState, + Q_FUNC_INFO, "Invalid state"); + + if (KErrNone == aError) + startRecording(); +} + +void SymbianAudioInput::ToneFinished(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound's tone playback functions, so should + // never receive this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioInput::BufferToBeFilled(CMMFBuffer *aBuffer) +{ + Q_UNUSED(aBuffer) + // This class doesn't use DevSound in play mode, so should never receive + // this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioInput::PlayError(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound in play mode, so should never receive + // this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioInput::BufferToBeEmptied(CMMFBuffer *aBuffer) +{ + // Following receipt of this callback, DevSound should not provide another + // buffer until we have returned the current one. + Q_ASSERT_X(!m_devSoundBuffer, Q_FUNC_INFO, "Buffer already held"); + + CMMFDataBuffer *const buffer = static_cast(aBuffer); + + if (!m_devSoundBufferSize) + m_devSoundBufferSize = buffer->Data().MaxLength(); + + m_totalBytesReady += buffer->Data().Length(); + + if (SymbianAudio::SuspendedState == m_internalState) { + m_devSoundBufferQ.append(buffer); + } else { + // Will be returned to DevSound by bufferEmptied(). + m_devSoundBuffer = buffer; + m_devSoundBufferPos = 0; + + if (bytesReady() && !m_pullMode) + pushData(); + } +} + +void SymbianAudioInput::RecordError(TInt aError) +{ + Q_UNUSED(aError) + setError(QAudio::IOError); +} + +void SymbianAudioInput::ConvertError(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound's format conversion functions, so + // should never receive this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioInput::DeviceMessage(TUid aMessageType, const TDesC8 &aMsg) +{ + Q_UNUSED(aMessageType) + Q_UNUSED(aMsg) + // Ignore this callback. +} + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void SymbianAudioInput::open() +{ + Q_ASSERT_X(SymbianAudio::ClosedState == m_internalState, + Q_FUNC_INFO, "DevSound already opened"); + + QT_TRAP_THROWING( m_devSound.reset(CMMFDevSound::NewL()) ) + + QScopedPointer caps( + new SymbianAudio::DevSoundCapabilities(*m_devSound, QAudio::AudioInput)); + + int err = SymbianAudio::Utils::isFormatSupported(m_format, *caps) ? + KErrNone : KErrNotSupported; + + if (KErrNone == err) { + setState(SymbianAudio::InitializingState); + TRAP(err, m_devSound->InitializeL(*this, m_nativeFourCC, + EMMFStateRecording)); + } + + if (KErrNone != err) { + setError(QAudio::OpenError); + m_devSound.reset(); + } +} + +void SymbianAudioInput::startRecording() +{ + const int samplesRecorded = m_devSound->SamplesRecorded(); + Q_ASSERT(samplesRecorded == 0); + + TRAPD(err, startDevSoundL()); + if (KErrNone == err) { + startDataTransfer(); + } else { + setError(QAudio::OpenError); + close(); + } +} + +void SymbianAudioInput::startDevSoundL() +{ + TMMFCapabilities nativeFormat = m_devSound->Config(); + m_nativeFormat.iBufferSize = nativeFormat.iBufferSize; + m_devSound->SetConfigL(m_nativeFormat); + m_devSound->RecordInitL(); +} + +void SymbianAudioInput::startDataTransfer() +{ + m_notifyTimer->start(m_notifyInterval); + + if (m_pullMode) + m_pullTimer->start(); + + if (bytesReady()) { + setState(SymbianAudio::ActiveState); + if (!m_pullMode) + pushData(); + } else { + if (SymbianAudio::SuspendedState == m_internalState) + setState(SymbianAudio::ActiveState); + else + setState(SymbianAudio::IdleState); + } +} + +CMMFDataBuffer* SymbianAudioInput::currentBuffer() const +{ + CMMFDataBuffer *result = m_devSoundBuffer; + if (!result && !m_devSoundBufferQ.empty()) + result = m_devSoundBufferQ.front(); + return result; +} + +void SymbianAudioInput::pushData() +{ + Q_ASSERT_X(bytesReady(), Q_FUNC_INFO, "No data available"); + Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO, "pushData called when in pull mode"); + qobject_cast(m_sink)->dataReady(); +} + +qint64 SymbianAudioInput::read(char *data, qint64 len) +{ + // SymbianAudioInputPrivate is ready to read data + + Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO, + "read called when in pull mode"); + + qint64 bytesRead = 0; + + CMMFDataBuffer *buffer = 0; + while ((buffer = currentBuffer()) && (bytesRead < len)) { + if (SymbianAudio::IdleState == m_internalState) + setState(SymbianAudio::ActiveState); + + TDesC8 &inputBuffer = buffer->Data(); + + const qint64 inputBytes = bytesReady(); + const qint64 outputBytes = len - bytesRead; + const qint64 copyBytes = outputBytes < inputBytes ? + outputBytes : inputBytes; + + memcpy(data, inputBuffer.Ptr() + m_devSoundBufferPos, copyBytes); + + m_devSoundBufferPos += copyBytes; + data += copyBytes; + bytesRead += copyBytes; + + if (!bytesReady()) + bufferEmptied(); + } + + return bytesRead; +} + +void SymbianAudioInput::pullData() +{ + Q_ASSERT_X(m_pullMode, Q_FUNC_INFO, + "pullData called when in push mode"); + + CMMFDataBuffer *buffer = 0; + while (buffer = currentBuffer()) { + if (SymbianAudio::IdleState == m_internalState) + setState(SymbianAudio::ActiveState); + + TDesC8 &inputBuffer = buffer->Data(); + + const qint64 inputBytes = bytesReady(); + const qint64 bytesPushed = m_sink->write( + (char*)inputBuffer.Ptr() + m_devSoundBufferPos, inputBytes); + + m_devSoundBufferPos += bytesPushed; + + if (!bytesReady()) + bufferEmptied(); + + if (!bytesPushed) + break; + } +} + +void SymbianAudioInput::bufferEmptied() +{ + m_devSoundBufferPos = 0; + + if (m_devSoundBuffer) { + m_totalBytesReady -= m_devSoundBuffer->Data().Length(); + m_devSoundBuffer = 0; + m_devSound->RecordData(); + } else { + Q_ASSERT(!m_devSoundBufferQ.empty()); + m_totalBytesReady -= m_devSoundBufferQ.front()->Data().Length(); + m_devSoundBufferQ.erase(m_devSoundBufferQ.begin()); + + // If the queue has been emptied, resume transfer from the hardware + if (m_devSoundBufferQ.empty()) + m_devSound->RecordInitL(); + } + + Q_ASSERT(m_totalBytesReady >= 0); +} + +void SymbianAudioInput::close() +{ + m_notifyTimer->stop(); + m_pullTimer->stop(); + + m_error = QAudio::NoError; + + if (m_devSound) + m_devSound->Stop(); + m_devSound.reset(); + m_devSoundBuffer = 0; + m_devSoundBufferSize = 0; + m_totalBytesReady = 0; + + if (!m_pullMode) // m_sink is owned + delete m_sink; + m_pullMode = false; + m_sink = 0; + + m_devSoundBufferQ.clear(); + m_devSoundBufferPos = 0; + m_totalSamplesRecorded = 0; + + setState(SymbianAudio::ClosedState); +} + +qint64 SymbianAudioInput::getSamplesRecorded() const +{ + qint64 result = 0; + if (m_devSound) + result = qint64(m_devSound->SamplesRecorded()); + return result; +} + +void SymbianAudioInput::setError(QAudio::Error error) +{ + m_error = error; + + // Although no state transition actually occurs here, a stateChanged event + // must be emitted to inform the client that the call to start() was + // unsuccessful. + if (QAudio::OpenError == error) + emit stateChanged(QAudio::StoppedState); + + // Close the DevSound instance. This causes a transition to StoppedState. + // This must be done asynchronously in case the current function was called + // from a DevSound event handler, in which case deleting the DevSound + // instance may cause an exception. + QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); +} + +void SymbianAudioInput::setState(SymbianAudio::State newInternalState) +{ + const QAudio::State oldExternalState = m_externalState; + m_internalState = newInternalState; + m_externalState = SymbianAudio::Utils::stateNativeToQt( + m_internalState, initializingState()); + + if (m_externalState != oldExternalState) + emit stateChanged(m_externalState); +} + +QAudio::State SymbianAudioInput::initializingState() const +{ + return QAudio::IdleState; +} + +QT_END_NAMESPACE diff --git a/src/plugins/audio/symbian/symbianaudioinput.h b/src/plugins/audio/symbian/symbianaudioinput.h new file mode 100644 index 0000000..0497d7a --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudioinput.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANAUDIOINPUT_H +#define SYMBIANAUDIOINPUT_H + +#include +#include +#include +#include +#include "symbianaudio.h" + +QT_BEGIN_NAMESPACE + +class SymbianAudioInput; + +class SymbianAudioInputPrivate : public QIODevice +{ + friend class SymbianAudioInput; + Q_OBJECT +public: + SymbianAudioInputPrivate(SymbianAudioInput *audio); + ~SymbianAudioInputPrivate(); + + qint64 readData(char *data, qint64 len); + qint64 writeData(const char *data, qint64 len); + + void dataReady(); + +private: + SymbianAudioInput *const m_audioDevice; +}; + +class SymbianAudioInput + : public QAbstractAudioInput + , public MDevSoundObserver +{ + friend class SymbianAudioInputPrivate; + Q_OBJECT +public: + SymbianAudioInput(const QByteArray &device, + const QAudioFormat &audioFormat); + ~SymbianAudioInput(); + + // QAbstractAudioInput + QIODevice* start(QIODevice *device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + int bytesReady() const; + int periodSize() const; + void setBufferSize(int value); + int bufferSize() const; + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + qint64 processedUSecs() const; + qint64 elapsedUSecs() const; + QAudio::Error error() const; + QAudio::State state() const; + QAudioFormat format() const; + + // MDevSoundObserver + void InitializeComplete(TInt aError); + void ToneFinished(TInt aError); + void BufferToBeFilled(CMMFBuffer *aBuffer); + void PlayError(TInt aError); + void BufferToBeEmptied(CMMFBuffer *aBuffer); + void RecordError(TInt aError); + void ConvertError(TInt aError); + void DeviceMessage(TUid aMessageType, const TDesC8 &aMsg); + +private slots: + void pullData(); + +private: + void open(); + void startRecording(); + void startDevSoundL(); + void startDataTransfer(); + CMMFDataBuffer* currentBuffer() const; + void pushData(); + qint64 read(char *data, qint64 len); + void bufferEmptied(); + Q_INVOKABLE void close(); + + qint64 getSamplesRecorded() const; + + void setError(QAudio::Error error); + void setState(SymbianAudio::State state); + + QAudio::State initializingState() const; + +private: + const QByteArray m_device; + const QAudioFormat m_format; + + int m_clientBufferSize; + int m_notifyInterval; + QScopedPointer m_notifyTimer; + QTime m_elapsed; + QAudio::Error m_error; + + SymbianAudio::State m_internalState; + QAudio::State m_externalState; + + bool m_pullMode; + QIODevice *m_sink; + + QScopedPointer m_pullTimer; + + QScopedPointer m_devSound; + TUint32 m_nativeFourCC; + TMMFCapabilities m_nativeFormat; + + // Latest buffer provided by DevSound, to be empied of data. + CMMFDataBuffer *m_devSoundBuffer; + + int m_devSoundBufferSize; + + // Total amount of data in buffers provided by DevSound + int m_totalBytesReady; + + // Queue of buffers returned after call to CMMFDevSound::Pause(). + QList m_devSoundBufferQ; + + // Current read position within m_devSoundBuffer + qint64 m_devSoundBufferPos; + + // Samples recorded up to the last call to suspend(). It is necessary + // to cache this because suspend() is implemented using + // CMMFDevSound::Stop(), which resets DevSound's SamplesRecorded() counter. + quint32 m_totalSamplesRecorded; + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/audio/symbian/symbianaudiooutput.cpp b/src/plugins/audio/symbian/symbianaudiooutput.cpp new file mode 100644 index 0000000..7e05211 --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudiooutput.cpp @@ -0,0 +1,697 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianaudiooutput.h" +#include "symbianaudioutils.h" + +QT_BEGIN_NAMESPACE + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +const int UnderflowTimerInterval = 50; // ms + + +//----------------------------------------------------------------------------- +// Private class +//----------------------------------------------------------------------------- + +SymbianAudioOutputPrivate::SymbianAudioOutputPrivate( + SymbianAudioOutput *audioDevice) + : m_audioDevice(audioDevice) +{ + +} + +SymbianAudioOutputPrivate::~SymbianAudioOutputPrivate() +{ + +} + +qint64 SymbianAudioOutputPrivate::readData(char *data, qint64 len) +{ + Q_UNUSED(data) + Q_UNUSED(len) + return 0; +} + +qint64 SymbianAudioOutputPrivate::writeData(const char *data, qint64 len) +{ + qint64 totalWritten = 0; + + if (m_audioDevice->state() == QAudio::ActiveState || + m_audioDevice->state() == QAudio::IdleState) { + + while (totalWritten < len) { + const qint64 written = m_audioDevice->pushData(data + totalWritten, + len - totalWritten); + if (written > 0) + totalWritten += written; + else + break; + } + } + + return totalWritten; +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +SymbianAudioOutput::SymbianAudioOutput(const QByteArray &device, + const QAudioFormat &format) + : m_device(device) + , m_format(format) + , m_clientBufferSize(SymbianAudio::DefaultBufferSize) + , m_notifyInterval(SymbianAudio::DefaultNotifyInterval) + , m_notifyTimer(new QTimer(this)) + , m_error(QAudio::NoError) + , m_internalState(SymbianAudio::ClosedState) + , m_externalState(QAudio::StoppedState) + , m_pullMode(false) + , m_source(0) + , m_devSoundBuffer(0) + , m_devSoundBufferSize(0) + , m_bytesWritten(0) + , m_pushDataReady(false) + , m_bytesPadding(0) + , m_underflow(false) + , m_lastBuffer(false) + , m_underflowTimer(new QTimer(this)) + , m_samplesPlayed(0) + , m_totalSamplesPlayed(0) +{ + connect(m_notifyTimer.data(), SIGNAL(timeout()), this, SIGNAL(notify())); + + SymbianAudio::Utils::formatQtToNative(m_format, m_nativeFourCC, + m_nativeFormat); + + m_underflowTimer->setInterval(UnderflowTimerInterval); + connect(m_underflowTimer.data(), SIGNAL(timeout()), this, + SLOT(underflowTimerExpired())); +} + +SymbianAudioOutput::~SymbianAudioOutput() +{ + close(); +} + +QIODevice* SymbianAudioOutput::start(QIODevice *device) +{ + stop(); + + // We have to set these before the call to open() because of the + // logic in initializingState() + if (device) { + m_pullMode = true; + m_source = device; + } + + open(); + + if (SymbianAudio::ClosedState != m_internalState) { + if (device) { + connect(m_source, SIGNAL(readyRead()), this, SLOT(dataReady())); + } else { + m_source = new SymbianAudioOutputPrivate(this); + m_source->open(QIODevice::WriteOnly | QIODevice::Unbuffered); + } + + m_elapsed.restart(); + } + + return m_source; +} + +void SymbianAudioOutput::stop() +{ + close(); +} + +void SymbianAudioOutput::reset() +{ + m_totalSamplesPlayed += getSamplesPlayed(); + m_devSound->Stop(); + m_bytesPadding = 0; + startPlayback(); +} + +void SymbianAudioOutput::suspend() +{ + if (SymbianAudio::ActiveState == m_internalState + || SymbianAudio::IdleState == m_internalState) { + m_notifyTimer->stop(); + m_underflowTimer->stop(); + + const qint64 samplesWritten = SymbianAudio::Utils::bytesToSamples( + m_format, m_bytesWritten); + m_bytesWritten = 0; + + const qint64 samplesPlayed = getSamplesPlayed(); + + // CMMFDevSound::Pause() is not guaranteed to work correctly in all + // implementations, for play-mode DevSound sessions. We therefore + // have to implement suspend() by calling CMMFDevSound::Stop(). + // Because this causes buffered data to be dropped, we replace the + // lost data with silence following a call to resume(), in order to + // ensure that processedUSecs() returns the correct value. + m_devSound->Stop(); + m_totalSamplesPlayed += samplesPlayed; + + // Calculate the amount of data dropped + const qint64 paddingSamples = samplesWritten - samplesPlayed; + m_bytesPadding = SymbianAudio::Utils::samplesToBytes(m_format, + paddingSamples); + + setState(SymbianAudio::SuspendedState); + } +} + +void SymbianAudioOutput::resume() +{ + if (SymbianAudio::SuspendedState == m_internalState) + startPlayback(); +} + +int SymbianAudioOutput::bytesFree() const +{ + int result = 0; + if (m_devSoundBuffer) { + const TDes8 &outputBuffer = m_devSoundBuffer->Data(); + result = outputBuffer.MaxLength() - outputBuffer.Length(); + } + return result; +} + +int SymbianAudioOutput::periodSize() const +{ + return bufferSize(); +} + +void SymbianAudioOutput::setBufferSize(int value) +{ + // Note that DevSound does not allow its client to specify the buffer size. + // This functionality is available via custom interfaces, but since these + // cannot be guaranteed to work across all DevSound implementations, we + // do not use them here. + // In order to comply with the expected bevahiour of QAudioOutput, we store + // the value and return it from bufferSize(), but the underlying DevSound + // buffer size remains unchanged. + if (value > 0) + m_clientBufferSize = value; +} + +int SymbianAudioOutput::bufferSize() const +{ + return m_devSoundBufferSize ? m_devSoundBufferSize : m_clientBufferSize; +} + +void SymbianAudioOutput::setNotifyInterval(int ms) +{ + if (ms > 0) { + const int oldNotifyInterval = m_notifyInterval; + m_notifyInterval = ms; + if (m_notifyTimer->isActive() && ms != oldNotifyInterval) + m_notifyTimer->start(m_notifyInterval); + } +} + +int SymbianAudioOutput::notifyInterval() const +{ + return m_notifyInterval; +} + +qint64 SymbianAudioOutput::processedUSecs() const +{ + int samplesPlayed = 0; + if (m_devSound && SymbianAudio::SuspendedState != m_internalState) + samplesPlayed = getSamplesPlayed(); + + // Protect against division by zero + Q_ASSERT_X(m_format.frequency() > 0, Q_FUNC_INFO, "Invalid frequency"); + + const qint64 result = qint64(1000000) * + (samplesPlayed + m_totalSamplesPlayed) + / m_format.frequency(); + + return result; +} + +qint64 SymbianAudioOutput::elapsedUSecs() const +{ + const qint64 result = (QAudio::StoppedState == state()) ? + 0 : m_elapsed.elapsed() * 1000; + return result; +} + +QAudio::Error SymbianAudioOutput::error() const +{ + return m_error; +} + +QAudio::State SymbianAudioOutput::state() const +{ + return m_externalState; +} + +QAudioFormat SymbianAudioOutput::format() const +{ + return m_format; +} + +//----------------------------------------------------------------------------- +// MDevSoundObserver implementation +//----------------------------------------------------------------------------- + +void SymbianAudioOutput::InitializeComplete(TInt aError) +{ + Q_ASSERT_X(SymbianAudio::InitializingState == m_internalState, + Q_FUNC_INFO, "Invalid state"); + + if (KErrNone == aError) + startPlayback(); +} + +void SymbianAudioOutput::ToneFinished(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound's tone playback functions, so should + // never receive this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioOutput::BufferToBeFilled(CMMFBuffer *aBuffer) +{ + // Following receipt of this callback, DevSound should not provide another + // buffer until we have returned the current one. + Q_ASSERT_X(!m_devSoundBuffer, Q_FUNC_INFO, "Buffer already held"); + + // Will be returned to DevSound by bufferFilled(). + m_devSoundBuffer = static_cast(aBuffer); + + if (!m_devSoundBufferSize) + m_devSoundBufferSize = m_devSoundBuffer->Data().MaxLength(); + + writePaddingData(); + + if (m_pullMode && isDataReady() && !m_bytesPadding) + pullData(); +} + +void SymbianAudioOutput::PlayError(TInt aError) +{ + switch (aError) { + case KErrUnderflow: + m_underflow = true; + if (m_pullMode && !m_lastBuffer) + setError(QAudio::UnderrunError); + else + setState(SymbianAudio::IdleState); + break; + default: + setError(QAudio::IOError); + break; + } +} + +void SymbianAudioOutput::BufferToBeEmptied(CMMFBuffer *aBuffer) +{ + Q_UNUSED(aBuffer) + // This class doesn't use DevSound in record mode, so should never receive + // this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioOutput::RecordError(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound in record mode, so should never receive + // this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioOutput::ConvertError(TInt aError) +{ + Q_UNUSED(aError) + // This class doesn't use DevSound's format conversion functions, so + // should never receive this callback. + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback"); +} + +void SymbianAudioOutput::DeviceMessage(TUid aMessageType, const TDesC8 &aMsg) +{ + Q_UNUSED(aMessageType) + Q_UNUSED(aMsg) + // Ignore this callback. +} + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void SymbianAudioOutput::dataReady() +{ + // Client-provided QIODevice has data ready to read. + + Q_ASSERT_X(m_source->bytesAvailable(), Q_FUNC_INFO, + "readyRead signal received, but no data available"); + + if (!m_bytesPadding) + pullData(); +} + +void SymbianAudioOutput::underflowTimerExpired() +{ + const TInt samplesPlayed = getSamplesPlayed(); + if (m_samplesPlayed && (samplesPlayed == m_samplesPlayed)) { + setError(QAudio::UnderrunError); + } else { + m_samplesPlayed = samplesPlayed; + m_underflowTimer->start(); + } +} + +void SymbianAudioOutput::open() +{ + Q_ASSERT_X(SymbianAudio::ClosedState == m_internalState, + Q_FUNC_INFO, "DevSound already opened"); + + QT_TRAP_THROWING( m_devSound.reset(CMMFDevSound::NewL()) ) + + QScopedPointer caps( + new SymbianAudio::DevSoundCapabilities(*m_devSound, + QAudio::AudioOutput)); + + int err = SymbianAudio::Utils::isFormatSupported(m_format, *caps) ? + KErrNone : KErrNotSupported; + + if (KErrNone == err) { + setState(SymbianAudio::InitializingState); + TRAP(err, m_devSound->InitializeL(*this, m_nativeFourCC, + EMMFStatePlaying)); + } + + if (KErrNone != err) { + setError(QAudio::OpenError); + m_devSound.reset(); + } +} + +void SymbianAudioOutput::startPlayback() +{ + TRAPD(err, startDevSoundL()); + if (KErrNone == err) { + if (isDataReady()) + setState(SymbianAudio::ActiveState); + else + setState(SymbianAudio::IdleState); + + m_notifyTimer->start(m_notifyInterval); + m_underflow = false; + + Q_ASSERT(m_devSound->SamplesPlayed() == 0); + + writePaddingData(); + + if (m_pullMode && m_source->bytesAvailable() && !m_bytesPadding) + dataReady(); + } else { + setError(QAudio::OpenError); + close(); + } +} + +void SymbianAudioOutput::startDevSoundL() +{ + TMMFCapabilities nativeFormat = m_devSound->Config(); + m_nativeFormat.iBufferSize = nativeFormat.iBufferSize; + m_devSound->SetConfigL(m_nativeFormat); + m_devSound->PlayInitL(); +} + +void SymbianAudioOutput::writePaddingData() +{ + // See comments in suspend() + + while (m_devSoundBuffer && m_bytesPadding) { + if (SymbianAudio::IdleState == m_internalState) + setState(SymbianAudio::ActiveState); + + TDes8 &outputBuffer = m_devSoundBuffer->Data(); + const qint64 outputBytes = bytesFree(); + const qint64 paddingBytes = outputBytes < m_bytesPadding ? + outputBytes : m_bytesPadding; + unsigned char *ptr = const_cast(outputBuffer.Ptr()); + Mem::FillZ(ptr, paddingBytes); + outputBuffer.SetLength(outputBuffer.Length() + paddingBytes); + m_bytesPadding -= paddingBytes; + + if (m_pullMode && m_source->atEnd()) + lastBufferFilled(); + if (paddingBytes == outputBytes) + bufferFilled(); + } +} + +qint64 SymbianAudioOutput::pushData(const char *data, qint64 len) +{ + // Data has been written to SymbianAudioOutputPrivate + + Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO, + "pushData called when in pull mode"); + + const unsigned char *const inputPtr = + reinterpret_cast(data); + qint64 bytesWritten = 0; + + if (SymbianAudio::IdleState == m_internalState) + setState(SymbianAudio::ActiveState); + + while (m_devSoundBuffer && (bytesWritten < len)) { + // writePaddingData() is called from BufferToBeFilled(), so we should + // never have any padding data left at this point. + Q_ASSERT_X(0 == m_bytesPadding, Q_FUNC_INFO, + "Padding bytes remaining in pushData"); + + TDes8 &outputBuffer = m_devSoundBuffer->Data(); + + const qint64 outputBytes = bytesFree(); + const qint64 inputBytes = len - bytesWritten; + const qint64 copyBytes = outputBytes < inputBytes ? + outputBytes : inputBytes; + + outputBuffer.Append(inputPtr + bytesWritten, copyBytes); + bytesWritten += copyBytes; + + bufferFilled(); + } + + m_pushDataReady = (bytesWritten < len); + + // If DevSound is still initializing (m_internalState == InitializingState), + // we cannot transition m_internalState to ActiveState, but we must emit + // an (external) state change from IdleState to ActiveState. The following + // call triggers this signal. + setState(m_internalState); + + return bytesWritten; +} + +void SymbianAudioOutput::pullData() +{ + Q_ASSERT_X(m_pullMode, Q_FUNC_INFO, + "pullData called when in push mode"); + + if (m_bytesPadding) + m_bytesPadding = 1; + + // writePaddingData() is called by BufferToBeFilled() before pullData(), + // so we should never have any padding data left at this point. + Q_ASSERT_X(0 == m_bytesPadding, Q_FUNC_INFO, + "Padding bytes remaining in pullData"); + + qint64 inputBytes = m_source->bytesAvailable(); + while (m_devSoundBuffer && inputBytes) { + if (SymbianAudio::IdleState == m_internalState) + setState(SymbianAudio::ActiveState); + + TDes8 &outputBuffer = m_devSoundBuffer->Data(); + + const qint64 outputBytes = bytesFree(); + const qint64 copyBytes = outputBytes < inputBytes ? + outputBytes : inputBytes; + + char *outputPtr = (char*)(outputBuffer.Ptr() + outputBuffer.Length()); + const qint64 bytesCopied = m_source->read(outputPtr, copyBytes); + Q_ASSERT(bytesCopied == copyBytes); + outputBuffer.SetLength(outputBuffer.Length() + bytesCopied); + inputBytes -= bytesCopied; + + if (m_source->atEnd()) + lastBufferFilled(); + else if (copyBytes == outputBytes) + bufferFilled(); + } +} + +void SymbianAudioOutput::bufferFilled() +{ + Q_ASSERT_X(m_devSoundBuffer, Q_FUNC_INFO, "No buffer to return"); + + const TDes8 &outputBuffer = m_devSoundBuffer->Data(); + m_bytesWritten += outputBuffer.Length(); + + m_devSoundBuffer = 0; + + m_samplesPlayed = getSamplesPlayed(); + m_underflowTimer->start(); + + if (QAudio::UnderrunError == m_error) + m_error = QAudio::NoError; + + m_devSound->PlayData(); +} + +void SymbianAudioOutput::lastBufferFilled() +{ + Q_ASSERT_X(m_devSoundBuffer, Q_FUNC_INFO, "No buffer to fill"); + Q_ASSERT_X(!m_lastBuffer, Q_FUNC_INFO, "Last buffer already sent"); + m_lastBuffer = true; + m_devSoundBuffer->SetLastBuffer(ETrue); + bufferFilled(); +} + +void SymbianAudioOutput::close() +{ + m_notifyTimer->stop(); + m_underflowTimer->stop(); + + m_error = QAudio::NoError; + + if (m_devSound) + m_devSound->Stop(); + m_devSound.reset(); + m_devSoundBuffer = 0; + m_devSoundBufferSize = 0; + + if (!m_pullMode) // m_source is owned + delete m_source; + m_pullMode = false; + m_source = 0; + + m_bytesWritten = 0; + m_pushDataReady = false; + m_bytesPadding = 0; + m_underflow = false; + m_lastBuffer = false; + m_samplesPlayed = 0; + m_totalSamplesPlayed = 0; + + setState(SymbianAudio::ClosedState); +} + +qint64 SymbianAudioOutput::getSamplesPlayed() const +{ + qint64 result = 0; + if (m_devSound) { + const qint64 samplesWritten = SymbianAudio::Utils::bytesToSamples( + m_format, m_bytesWritten); + + if (m_underflow) { + result = samplesWritten; + } else { + // This is necessary because some DevSound implementations report + // that they have played more data than has actually been provided to them + // by the client. + const qint64 devSoundSamplesPlayed(m_devSound->SamplesPlayed()); + result = qMin(devSoundSamplesPlayed, samplesWritten); + } + } + return result; +} + +void SymbianAudioOutput::setError(QAudio::Error error) +{ + m_error = error; + + // Although no state transition actually occurs here, a stateChanged event + // must be emitted to inform the client that the call to start() was + // unsuccessful. + if (QAudio::OpenError == error) + emit stateChanged(QAudio::StoppedState); + + if (QAudio::UnderrunError == error) + setState(SymbianAudio::IdleState); + else + // Close the DevSound instance. This causes a transition to + // StoppedState. This must be done asynchronously in case the + // current function was called from a DevSound event handler, in which + // case deleting the DevSound instance may cause an exception. + QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); +} + +void SymbianAudioOutput::setState(SymbianAudio::State newInternalState) +{ + const QAudio::State oldExternalState = m_externalState; + m_internalState = newInternalState; + m_externalState = SymbianAudio::Utils::stateNativeToQt( + m_internalState, initializingState()); + + if (m_externalState != oldExternalState) + emit stateChanged(m_externalState); +} + +bool SymbianAudioOutput::isDataReady() const +{ + return (m_source && m_source->bytesAvailable()) + || m_bytesPadding + || m_pushDataReady; +} + +QAudio::State SymbianAudioOutput::initializingState() const +{ + return isDataReady() ? QAudio::ActiveState : QAudio::IdleState; +} + +QT_END_NAMESPACE diff --git a/src/plugins/audio/symbian/symbianaudiooutput.h b/src/plugins/audio/symbian/symbianaudiooutput.h new file mode 100644 index 0000000..4db97c3 --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudiooutput.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANAUDIOOUTPUT_H +#define SYMBIANAUDIOOUTPUT_H + +#include +#include +#include +#include +#include "symbianaudio.h" + +QT_BEGIN_NAMESPACE + +class SymbianAudioOutput; + +class SymbianAudioOutputPrivate : public QIODevice +{ + friend class SymbianAudioOutput; + Q_OBJECT +public: + SymbianAudioOutputPrivate(SymbianAudioOutput *audio); + ~SymbianAudioOutputPrivate(); + + qint64 readData(char *data, qint64 len); + qint64 writeData(const char *data, qint64 len); + +private: + SymbianAudioOutput *const m_audioDevice; +}; + +class SymbianAudioOutput + : public QAbstractAudioOutput + , public MDevSoundObserver +{ + friend class SymbianAudioOutputPrivate; + Q_OBJECT +public: + SymbianAudioOutput(const QByteArray &device, + const QAudioFormat &audioFormat); + ~SymbianAudioOutput(); + + // QAbstractAudioOutput + QIODevice* start(QIODevice *device = 0); + void stop(); + void reset(); + void suspend(); + void resume(); + int bytesFree() const; + int periodSize() const; + void setBufferSize(int value); + int bufferSize() const; + void setNotifyInterval(int milliSeconds); + int notifyInterval() const; + qint64 processedUSecs() const; + qint64 elapsedUSecs() const; + QAudio::Error error() const; + QAudio::State state() const; + QAudioFormat format() const; + + // MDevSoundObserver + void InitializeComplete(TInt aError); + void ToneFinished(TInt aError); + void BufferToBeFilled(CMMFBuffer *aBuffer); + void PlayError(TInt aError); + void BufferToBeEmptied(CMMFBuffer *aBuffer); + void RecordError(TInt aError); + void ConvertError(TInt aError); + void DeviceMessage(TUid aMessageType, const TDesC8 &aMsg); + +private slots: + void dataReady(); + void underflowTimerExpired(); + +private: + void open(); + void startPlayback(); + void startDevSoundL(); + void writePaddingData(); + qint64 pushData(const char *data, qint64 len); + void pullData(); + void bufferFilled(); + void lastBufferFilled(); + Q_INVOKABLE void close(); + + qint64 getSamplesPlayed() const; + + void setError(QAudio::Error error); + void setState(SymbianAudio::State state); + + bool isDataReady() const; + QAudio::State initializingState() const; + +private: + const QByteArray m_device; + const QAudioFormat m_format; + + int m_clientBufferSize; + int m_notifyInterval; + QScopedPointer m_notifyTimer; + QTime m_elapsed; + QAudio::Error m_error; + + SymbianAudio::State m_internalState; + QAudio::State m_externalState; + + bool m_pullMode; + QIODevice *m_source; + + QScopedPointer m_devSound; + TUint32 m_nativeFourCC; + TMMFCapabilities m_nativeFormat; + + // Buffer provided by DevSound, to be filled with data. + CMMFDataBuffer *m_devSoundBuffer; + + int m_devSoundBufferSize; + + // Number of bytes transferred from QIODevice to QAudioOutput. It is + // necessary to count this because data is dropped when suspend() is + // called. The difference between the position reported by DevSound and + // this value allows us to calculate m_bytesPadding; + quint32 m_bytesWritten; + + // True if client has provided data while the audio subsystem was not + // ready to consume it. + bool m_pushDataReady; + + // Number of zero bytes which will be written when client calls resume(). + quint32 m_bytesPadding; + + // True if PlayError(KErrUnderflow) has been called. + bool m_underflow; + + // True if a buffer marked with the "last buffer" flag has been provided + // to DevSound. + bool m_lastBuffer; + + // Some DevSound implementations ignore all underflow errors raised by the + // audio driver, unless the last buffer flag has been set by the client. + // In push-mode playback, this flag will never be set, so the underflow + // error will never be reported. In order to work around this, a timer + // is used, which gets reset every time the client provides more data. If + // the timer expires, an underflow error is raised by this object. + QScopedPointer m_underflowTimer; + + // Result of previous call to CMMFDevSound::SamplesPlayed(). This value is + // used to determine whether, when m_underflowTimer expires, an + // underflow error has actually occurred. + quint32 m_samplesPlayed; + + // Samples played up to the last call to suspend(). It is necessary + // to cache this because suspend() is implemented using + // CMMFDevSound::Stop(), which resets DevSound's SamplesPlayed() counter. + quint32 m_totalSamplesPlayed; + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/audio/symbian/symbianaudioutils.cpp b/src/plugins/audio/symbian/symbianaudioutils.cpp new file mode 100644 index 0000000..13ea03d --- /dev/null +++ b/src/plugins/audio/symbian/symbianaudioutils.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianaudioutils.h" +#include + +QT_BEGIN_NAMESPACE + +namespace SymbianAudio { + +DevSoundCapabilities::DevSoundCapabilities(CMMFDevSound &devsound, + QAudio::Mode mode) +{ + QT_TRAP_THROWING(constructL(devsound, mode)); +} + +DevSoundCapabilities::~DevSoundCapabilities() +{ + m_fourCC.Close(); +} + +void DevSoundCapabilities::constructL(CMMFDevSound &devsound, + QAudio::Mode mode) +{ + m_caps = devsound.Capabilities(); + + TMMFPrioritySettings settings; + + switch (mode) { + case QAudio::AudioOutput: + settings.iState = EMMFStatePlaying; + devsound.GetSupportedInputDataTypesL(m_fourCC, settings); + break; + + case QAudio::AudioInput: + settings.iState = EMMFStateRecording; + devsound.GetSupportedInputDataTypesL(m_fourCC, settings); + break; + + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid mode"); + } +} + +namespace Utils { + +//----------------------------------------------------------------------------- +// Static data +//----------------------------------------------------------------------------- + +// Sample rate / frequency + +typedef TMMFSampleRate SampleRateNative; +typedef int SampleRateQt; + +const int SampleRateCount = 12; + +const SampleRateNative SampleRateListNative[SampleRateCount] = { + EMMFSampleRate8000Hz + , EMMFSampleRate11025Hz + , EMMFSampleRate12000Hz + , EMMFSampleRate16000Hz + , EMMFSampleRate22050Hz + , EMMFSampleRate24000Hz + , EMMFSampleRate32000Hz + , EMMFSampleRate44100Hz + , EMMFSampleRate48000Hz + , EMMFSampleRate64000Hz + , EMMFSampleRate88200Hz + , EMMFSampleRate96000Hz +}; + +const SampleRateQt SampleRateListQt[SampleRateCount] = { + 8000 + , 11025 + , 12000 + , 16000 + , 22050 + , 24000 + , 32000 + , 44100 + , 48000 + , 64000 + , 88200 + , 96000 +}; + +// Channels + +typedef TMMFMonoStereo ChannelsNative; +typedef int ChannelsQt; + +const int ChannelsCount = 2; + +const ChannelsNative ChannelsListNative[ChannelsCount] = { + EMMFMono + , EMMFStereo +}; + +const ChannelsQt ChannelsListQt[ChannelsCount] = { + 1 + , 2 +}; + +// Encoding + +const int EncodingCount = 6; + +const TUint32 EncodingFourCC[EncodingCount] = { + KMMFFourCCCodePCM8 // 0 + , KMMFFourCCCodePCMU8 // 1 + , KMMFFourCCCodePCM16 // 2 + , KMMFFourCCCodePCMU16 // 3 + , KMMFFourCCCodePCM16B // 4 + , KMMFFourCCCodePCMU16B // 5 +}; + +// The characterised DevSound API specification states that the iEncoding +// field in TMMFCapabilities is ignored, and that the FourCC should be used +// to specify the PCM encoding. +// See "SGL.GT0287.102 Multimedia DevSound Baseline Compatibility.doc" in the +// mm_info/mm_docs repository. +const TMMFSoundEncoding EncodingNative[EncodingCount] = { + EMMFSoundEncoding16BitPCM // 0 + , EMMFSoundEncoding16BitPCM // 1 + , EMMFSoundEncoding16BitPCM // 2 + , EMMFSoundEncoding16BitPCM // 3 + , EMMFSoundEncoding16BitPCM // 4 + , EMMFSoundEncoding16BitPCM // 5 +}; + + +const int EncodingSampleSize[EncodingCount] = { + 8 // 0 + , 8 // 1 + , 16 // 2 + , 16 // 3 + , 16 // 4 + , 16 // 5 +}; + +const QAudioFormat::Endian EncodingByteOrder[EncodingCount] = { + QAudioFormat::LittleEndian // 0 + , QAudioFormat::LittleEndian // 1 + , QAudioFormat::LittleEndian // 2 + , QAudioFormat::LittleEndian // 3 + , QAudioFormat::BigEndian // 4 + , QAudioFormat::BigEndian // 5 +}; + +const QAudioFormat::SampleType EncodingSampleType[EncodingCount] = { + QAudioFormat::SignedInt // 0 + , QAudioFormat::UnSignedInt // 1 + , QAudioFormat::SignedInt // 2 + , QAudioFormat::UnSignedInt // 3 + , QAudioFormat::SignedInt // 4 + , QAudioFormat::UnSignedInt // 5 +}; + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +// Helper functions for implementing parameter conversions + +template +bool findValue(const Input *inputArray, int length, Input input, int &index) { + bool result = false; + for (int i=0; !result && i +bool convertValue(const Input *inputArray, const Output *outputArray, + int length, Input input, Output &output) { + int index; + const bool result = findValue(inputArray, length, input, index); + if (result) + output = outputArray[index]; + return result; +} + +/** + * Macro which is used to generate the implementation of the conversion + * functions. The implementation is just a wrapper around the templated + * convertValue function, e.g. + * + * CONVERSION_FUNCTION_IMPL(SampleRate, Qt, Native) + * + * expands to + * + * bool SampleRateQtToNative(int input, TMMFSampleRate &output) { + * return convertValue + * (SampleRateListQt, SampleRateListNative, SampleRateCount, + * input, output); + * } + */ +#define CONVERSION_FUNCTION_IMPL(FieldLc, Field, Input, Output) \ +bool FieldLc##Input##To##Output(Field##Input input, Field##Output &output) { \ + return convertValue(Field##List##Input, \ + Field##List##Output, Field##Count, input, output); \ +} + +//----------------------------------------------------------------------------- +// Local helper functions +//----------------------------------------------------------------------------- + +CONVERSION_FUNCTION_IMPL(sampleRate, SampleRate, Qt, Native) +CONVERSION_FUNCTION_IMPL(sampleRate, SampleRate, Native, Qt) +CONVERSION_FUNCTION_IMPL(channels, Channels, Qt, Native) +CONVERSION_FUNCTION_IMPL(channels, Channels, Native, Qt) + +bool sampleInfoQtToNative(int inputSampleSize, + QAudioFormat::Endian inputByteOrder, + QAudioFormat::SampleType inputSampleType, + TUint32 &outputFourCC, + TMMFSoundEncoding &outputEncoding) { + + bool found = false; + + for (int i=0; i &frequencies, + QList &channels, + QList &sampleSizes, + QList &byteOrders, + QList &sampleTypes) { + + frequencies.clear(); + sampleSizes.clear(); + byteOrders.clear(); + sampleTypes.clear(); + channels.clear(); + + for (int i=0; i +#include +#include +#include +#include "symbianaudio.h" + +QT_BEGIN_NAMESPACE + +namespace SymbianAudio { + +/* + * Helper class for querying DevSound codec / format support + */ +class DevSoundCapabilities { +public: + DevSoundCapabilities(CMMFDevSound &devsound, QAudio::Mode mode); + ~DevSoundCapabilities(); + + const RArray& fourCC() const { return m_fourCC; } + const TMMFCapabilities& caps() const { return m_caps; } + +private: + void constructL(CMMFDevSound &devsound, QAudio::Mode mode); + +private: + RArray m_fourCC; + TMMFCapabilities m_caps; +}; + +namespace Utils { + +/** + * Convert native audio capabilities to QAudio lists. + */ +void capabilitiesNativeToQt(const DevSoundCapabilities &caps, + QList &frequencies, + QList &channels, + QList &sampleSizes, + QList &byteOrders, + QList &sampleTypes); + +/** + * Check whether format is supported. + */ +bool isFormatSupported(const QAudioFormat &format, + const DevSoundCapabilities &caps); + +/** + * Convert QAudioFormat to native format types. + * + * Note that, despite the name, DevSound uses TMMFCapabilities to specify + * single formats as well as capabilities. + * + * Note that this function does not modify outputFormat.iBufferSize. + */ +bool formatQtToNative(const QAudioFormat &inputFormat, + TUint32 &outputFourCC, + TMMFCapabilities &outputFormat); + +/** + * Convert internal states to QAudio states. + */ +QAudio::State stateNativeToQt(State nativeState, + QAudio::State initializingState); + +/** + * Convert data length to number of samples. + */ +qint64 bytesToSamples(const QAudioFormat &format, qint64 length); + +/** + * Convert number of samples to data length. + */ +qint64 samplesToBytes(const QAudioFormat &format, qint64 samples); + +} // namespace Utils +} // namespace SymbianAudio + +QT_END_NAMESPACE + +#endif diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index a6a96ec..724451b 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -80,6 +80,9 @@ file=ABI_DIR\BUILD_DIR\qsvgicon.dll SHARED_LIB_DIR\qsvgicon.dll PAG // Phonon MMF backend file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll PAGED +// QtMultimedia audio backend +file=ABI_DIR\BUILD_DIR\qaudio.dll SHARED_LIB_DIR\qaudio.dll PAGED + // graphicssystems file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll PAGED @@ -109,6 +112,9 @@ data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin resou // Phonon MMF backend data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin +// QtMultimedia audio backend +data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio\qaudio.qtplugin + // graphicssystems data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 5318693..1f3b4a6 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -78,6 +78,12 @@ symbian: { DEPLOYMENT += phonon_backend_plugins } + contains(QT_CONFIG, audio-backend) { + qaudio_backend_plugins.sources += qaudio.dll + qaudio_backend_plugins.path = c:$$QT_PLUGINS_BASE_DIR/audio + DEPLOYMENT += qaudio_backend_plugins + } + # Support backup & restore for Qt libraries qtbackup.sources = backup_registration.xml qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) -- cgit v0.12 From edbacbac16b23b91209b3216505c873fbf87d1a2 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 18 Feb 2010 16:37:11 +0000 Subject: Pass QAudioDeviceInfo when creating audio input/output in examples Reviewed-by: trustme --- examples/multimedia/audioinput/audioinput.cpp | 2 +- examples/multimedia/audiooutput/audiooutput.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index 8a97640..b01a396 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -208,6 +208,7 @@ InputTest::InputTest() , m_modeButton(0) , m_suspendResumeButton(0) , m_deviceBox(0) + , m_device(QAudioDeviceInfo::defaultInputDevice()) , m_audioInfo(0) , m_audioInput(0) , m_input(0) @@ -279,7 +280,6 @@ void InputTest::initializeAudio() void InputTest::createAudioInput() { - m_audioInput = new QAudioInput(m_device, m_format, this); connect(m_audioInput, SIGNAL(notify()), SLOT(notified())); connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index 4866d36..cbadf02 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -160,6 +160,7 @@ AudioTest::AudioTest() , m_modeButton(0) , m_suspendResumeButton(0) , m_deviceBox(0) + , m_device(QAudioDeviceInfo::defaultOutputDevice()) , m_generator(0) , m_audioOutput(0) , m_output(0) @@ -226,7 +227,7 @@ void AudioTest::createAudioOutput() { delete m_audioOutput; m_audioOutput = 0; - m_audioOutput = new QAudioOutput(m_format, this); + m_audioOutput = new QAudioOutput(m_device, m_format, this); connect(m_audioOutput, SIGNAL(notify()), SLOT(notified())); connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); m_generator->start(); -- cgit v0.12 From 4c08defe1ac8342b9f8c6aeceebec12b839bae2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 18 Feb 2010 14:36:46 +0100 Subject: Simplify code, fix a compiler warning... profit! Well, it was a compiler warning on master... :-/ Reviewed-by: Janne Anttila Reviewed-by: axis --- src/gui/kernel/qsoftkeymanager.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index d3cef86..c9a94ee 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -210,13 +210,11 @@ bool QSoftKeyManager::handleUpdateSoftKeys() d->requestedSoftKeyActions.clear(); bool recursiveMerging = false; QWidget *source = softkeySource(NULL, recursiveMerging); - do { - if (source) { - bool added = appendSoftkeys(*source, level); - source = softkeySource(source, recursiveMerging); - level = added ? level + 1 : level; - } - } while (source); + while (source) { + if (appendSoftkeys(*source, level)) + ++level; + source = softkeySource(source, recursiveMerging); + } d->updateSoftKeys_sys(); return true; -- cgit v0.12 From 7f01b5aa56e61048a9785040e9807fd871a4b59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 18 Feb 2010 16:36:44 +0100 Subject: QTreeView: Fix premature pessimization Reviewed-by: Olivier Goffart --- src/gui/itemviews/qtreeview.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index d0fa22d..706d2a8 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2474,10 +2474,11 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) QVector insertedItems(delta); for (int i = 0; i < delta; ++i) { - insertedItems[i].index = d->model->index(i + start, 0, parent); - insertedItems[i].level = childLevel; - insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index); - insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); + QTreeViewItem &item = insertedItems[i]; + item.index = d->model->index(i + start, 0, parent); + item.level = childLevel; + item.hasChildren = d->hasVisibleChildren(item.index); + item.hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); } if (d->viewItems.isEmpty()) d->defaultItemHeight = indexRowSizeHint(insertedItems[0].index); -- cgit v0.12 From b408d94902ef0b2856a4c462e06fcc4412de49be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 12 Feb 2010 18:31:54 +0100 Subject: Fixing QDir benchmarks... The initial state of QDirIterator is ill-defined. If the hasNext returns true, then one must start by advancing the iterator to the first position. (Rinse, lather, repeat) --- tests/benchmarks/corelib/io/qdir/tst_qdir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp index aea9fd0..f2e52d2 100644 --- a/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp +++ b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp @@ -95,9 +95,9 @@ private slots: QBENCHMARK { QDirIterator dit(testdir.path(), QDir::Files); while (dit.hasNext()) { + dit.next(); dit.fileInfo().isDir(); dit.fileInfo().size(); - dit.next(); } } } @@ -116,9 +116,9 @@ private slots: QBENCHMARK { QDirIterator dit(testdir.path()); while (dit.hasNext()) { + dit.next(); dit.fileInfo().isDir(); dit.fileInfo().size(); - dit.next(); } } } -- cgit v0.12 From b8f9453eec3b218317a3dae0acfe444bc00c3093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 12 Feb 2010 18:36:41 +0100 Subject: Moving QDir benchmarks; making way for new test cases Also, removed dependency on QtGui; gave test case a more meaningful name; using bench_ prefix, instead of tst_ for benchmarks. --- tests/benchmarks/corelib/io/qdir/10000/10000.pro | 10 ++ .../corelib/io/qdir/10000/bench_qdir_10000.cpp | 198 +++++++++++++++++++++ tests/benchmarks/corelib/io/qdir/qdir.pro | 10 +- tests/benchmarks/corelib/io/qdir/tst_qdir.cpp | 198 --------------------- 4 files changed, 210 insertions(+), 206 deletions(-) create mode 100644 tests/benchmarks/corelib/io/qdir/10000/10000.pro create mode 100644 tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp delete mode 100644 tests/benchmarks/corelib/io/qdir/tst_qdir.cpp diff --git a/tests/benchmarks/corelib/io/qdir/10000/10000.pro b/tests/benchmarks/corelib/io/qdir/10000/10000.pro new file mode 100644 index 0000000..93b0992 --- /dev/null +++ b/tests/benchmarks/corelib/io/qdir/10000/10000.pro @@ -0,0 +1,10 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = bench_qdir_10000 +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += bench_qdir_10000.cpp + +QT -= gui diff --git a/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp new file mode 100644 index 0000000..b325250 --- /dev/null +++ b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#ifdef Q_OS_WIN +# include +#else +# include +# include +# include +# include +#endif + +class bench_QDir_10000 : public QObject{ + Q_OBJECT +public slots: + void initTestCase() { + QDir testdir = QDir::tempPath(); + + const QString subfolder_name = QLatin1String("test_speed"); + QVERIFY(testdir.mkdir(subfolder_name)); + QVERIFY(testdir.cd(subfolder_name)); + + for (uint i=0; i<10000; ++i) { + QFile file(testdir.absolutePath() + "/testfile_" + QString::number(i)); + file.open(QIODevice::WriteOnly); + } + } + void cleanupTestCase() { + { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); + foreach (const QString &filename, testdir.entryList()) { + testdir.remove(filename); + } + } + const QDir temp = QDir(QDir::tempPath()); + temp.rmdir(QLatin1String("test_speed")); + } +private slots: + void baseline() {} + + void sizeSpeed() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QFileInfoList fileInfoList = testdir.entryInfoList(QDir::Files, QDir::Unsorted); + foreach (const QFileInfo &fileInfo, fileInfoList) { + fileInfo.isDir(); + fileInfo.size(); + } + } + } + void sizeSpeedIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path(), QDir::Files); + while (dit.hasNext()) { + dit.next(); + dit.fileInfo().isDir(); + dit.fileInfo().size(); + } + } + } + + void sizeSpeedWithoutFilter() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QFileInfoList fileInfoList = testdir.entryInfoList(QDir::NoFilter, QDir::Unsorted); + foreach (const QFileInfo &fileInfo, fileInfoList) { + fileInfo.size(); + } + } + } + void sizeSpeedWithoutFilterIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path()); + while (dit.hasNext()) { + dit.next(); + dit.fileInfo().isDir(); + dit.fileInfo().size(); + } + } + } + + void sizeSpeedWithoutFileInfoList() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + QBENCHMARK { + QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); + foreach (const QString &filename, fileList) { + QFileInfo fileInfo(filename); + fileInfo.size(); + } + } + } + + void iDontWantAnyStat() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); + QBENCHMARK { + QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); + foreach (const QString &filename, fileList) { + + } + } + } + void iDontWantAnyStatIterator() { + QBENCHMARK { + QDirIterator dit(QDir::tempPath() + QLatin1String("/test_speed")); + while (dit.hasNext()) { + dit.next(); + } + } + } + + void sizeSpeedWithoutFilterLowLevel() { +#ifdef Q_OS_WIN + const wchar_t *dirpath = (wchar_t*)testdir.absolutePath().utf16(); + wchar_t appendedPath[MAX_PATH]; + wcscpy(appendedPath, dirpath); + wcscat(appendedPath, L"\\*"); + + WIN32_FIND_DATA fd; + HANDLE hSearch = FindFirstFileW(appendedPath, &fd); + QVERIFY(hSearch == INVALID_HANDLE_VALUE); + + QBENCHMARK { + do { + + } while (FindNextFile(hSearch, &fd)); + } + FindClose(hSearch); +#else + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + DIR *dir = opendir(qPrintable(testdir.absolutePath())); + QVERIFY(dir); + + QVERIFY(!chdir(qPrintable(testdir.absolutePath()))); + QBENCHMARK { + struct dirent *item = readdir(dir); + while (item) { + char *fileName = item->d_name; + + struct stat fileStat; + QVERIFY(!stat(fileName, &fileStat)); + + item = readdir(dir); + } + } + closedir(dir); +#endif + } +}; + +QTEST_MAIN(bench_QDir_10000) +#include "bench_qdir_10000.moc" diff --git a/tests/benchmarks/corelib/io/qdir/qdir.pro b/tests/benchmarks/corelib/io/qdir/qdir.pro index 2cdebfd..c572566 100644 --- a/tests/benchmarks/corelib/io/qdir/qdir.pro +++ b/tests/benchmarks/corelib/io/qdir/qdir.pro @@ -1,8 +1,2 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_qdir -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += tst_qdir.cpp +TEMPLATE = subdirs +SUBDIRS = 10000 diff --git a/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp deleted file mode 100644 index f2e52d2..0000000 --- a/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#ifdef Q_OS_WIN -# include -#else -# include -# include -# include -# include -#endif - -class Test : public QObject{ - Q_OBJECT -public slots: - void initTestCase() { - QDir testdir = QDir::tempPath(); - - const QString subfolder_name = QLatin1String("test_speed"); - QVERIFY(testdir.mkdir(subfolder_name)); - QVERIFY(testdir.cd(subfolder_name)); - - for (uint i=0; i<10000; ++i) { - QFile file(testdir.absolutePath() + "/testfile_" + QString::number(i)); - file.open(QIODevice::WriteOnly); - } - } - void cleanupTestCase() { - { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - testdir.setSorting(QDir::Unsorted); - testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); - foreach (const QString &filename, testdir.entryList()) { - testdir.remove(filename); - } - } - const QDir temp = QDir(QDir::tempPath()); - temp.rmdir(QLatin1String("test_speed")); - } -private slots: - void baseline() {} - - void sizeSpeed() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - QBENCHMARK { - QFileInfoList fileInfoList = testdir.entryInfoList(QDir::Files, QDir::Unsorted); - foreach (const QFileInfo &fileInfo, fileInfoList) { - fileInfo.isDir(); - fileInfo.size(); - } - } - } - void sizeSpeedIterator() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - QBENCHMARK { - QDirIterator dit(testdir.path(), QDir::Files); - while (dit.hasNext()) { - dit.next(); - dit.fileInfo().isDir(); - dit.fileInfo().size(); - } - } - } - - void sizeSpeedWithoutFilter() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - QBENCHMARK { - QFileInfoList fileInfoList = testdir.entryInfoList(QDir::NoFilter, QDir::Unsorted); - foreach (const QFileInfo &fileInfo, fileInfoList) { - fileInfo.size(); - } - } - } - void sizeSpeedWithoutFilterIterator() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - QBENCHMARK { - QDirIterator dit(testdir.path()); - while (dit.hasNext()) { - dit.next(); - dit.fileInfo().isDir(); - dit.fileInfo().size(); - } - } - } - - void sizeSpeedWithoutFileInfoList() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - testdir.setSorting(QDir::Unsorted); - QBENCHMARK { - QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); - foreach (const QString &filename, fileList) { - QFileInfo fileInfo(filename); - fileInfo.size(); - } - } - } - - void iDontWantAnyStat() { - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - testdir.setSorting(QDir::Unsorted); - testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); - QBENCHMARK { - QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); - foreach (const QString &filename, fileList) { - - } - } - } - void iDontWantAnyStatIterator() { - QBENCHMARK { - QDirIterator dit(QDir::tempPath() + QLatin1String("/test_speed")); - while (dit.hasNext()) { - dit.next(); - } - } - } - - void sizeSpeedWithoutFilterLowLevel() { -#ifdef Q_OS_WIN - const wchar_t *dirpath = (wchar_t*)testdir.absolutePath().utf16(); - wchar_t appendedPath[MAX_PATH]; - wcscpy(appendedPath, dirpath); - wcscat(appendedPath, L"\\*"); - - WIN32_FIND_DATA fd; - HANDLE hSearch = FindFirstFileW(appendedPath, &fd); - QVERIFY(hSearch == INVALID_HANDLE_VALUE); - - QBENCHMARK { - do { - - } while (FindNextFile(hSearch, &fd)); - } - FindClose(hSearch); -#else - QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - DIR *dir = opendir(qPrintable(testdir.absolutePath())); - QVERIFY(dir); - - QVERIFY(!chdir(qPrintable(testdir.absolutePath()))); - QBENCHMARK { - struct dirent *item = readdir(dir); - while (item) { - char *fileName = item->d_name; - - struct stat fileStat; - QVERIFY(!stat(fileName, &fileStat)); - - item = readdir(dir); - } - } - closedir(dir); -#endif - } -}; - -QTEST_MAIN(Test) -#include "tst_qdir.moc" -- cgit v0.12 From 603dc7d659084c5d092de79fec08a0baca8eaa59 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 19 Feb 2010 09:50:34 +0100 Subject: Revert "Factored epocRoot implementation out of qmake" This reverts commit 13cb80be958c40077245cbc4b36448a661e30c64. It breaks non-Symbian platforms. --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 5 - qmake/Makefile.win32-g++ | 4 - qmake/Makefile.win32-g++-sh | 4 - qmake/generators/symbian/epocroot.h | 51 +++++ .../symbian/initprojectdeploy_symbian.cpp | 96 ++++++++- .../generators/symbian/initprojectdeploy_symbian.h | 2 + qmake/generators/symbian/symmake.cpp | 3 - qmake/generators/symbian/symmake_abld.cpp | 3 - qmake/generators/symbian/symmake_sbsv2.cpp | 3 - qmake/project.cpp | 5 +- qmake/qmake.pri | 6 +- tools/shared/symbian/epocroot.cpp | 230 --------------------- tools/shared/symbian/epocroot.h | 67 ------ 14 files changed, 151 insertions(+), 337 deletions(-) create mode 100644 qmake/generators/symbian/epocroot.h delete mode 100644 tools/shared/symbian/epocroot.cpp delete mode 100644 tools/shared/symbian/epocroot.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 5469134..e343803 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -11,8 +11,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o \ - epocroot.o + registry.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -23,7 +22,6 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ registry.o \ - epocroot.o \ $(QTOBJS) @@ -37,7 +35,6 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ - $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -291,9 +288,6 @@ initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp -epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp @@ -302,7 +296,6 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp - #default rules .cpp.o: $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 48d84b7..3cd180c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -78,7 +78,6 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ registry.obj \ - epocroot.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -203,7 +202,6 @@ clean:: -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj -del registry.obj - -del epocroot.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -406,9 +404,6 @@ initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initproje registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp -epocroot.obj: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index 169de3c..ebc7fe2 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -40,7 +40,6 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ - epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -284,9 +283,6 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp -epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 98237e7..1d55da2 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -40,7 +40,6 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ - epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -283,9 +282,6 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp -epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp - project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/symbian/epocroot.h b/qmake/generators/symbian/epocroot.h new file mode 100644 index 0000000..be26438 --- /dev/null +++ b/qmake/generators/symbian/epocroot.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EPOCROOT_H +#define EPOCROOT_H + +#include + +// Implementation of epocRoot method is in initprojectdeploy_symbian.cpp +// Defined in separate header for inclusion clarity +extern QString epocRoot(); + +#endif // EPOCROOT_H diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 2a22305..5fbff58 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -46,15 +46,105 @@ #include #include -// Included from tools/shared -#include - #define SYSBIN_DIR "\\sys\\bin" #define SUFFIX_DLL "dll" #define SUFFIX_EXE "exe" #define SUFFIX_QTPLUGIN "qtplugin" +static void fixEpocRootStr(QString& path) +{ + path.replace("\\", "/"); + + if (path.size() > 1 && path[1] == QChar(':')) { + path = path.mid(2); + } + + if (!path.size() || path[path.size()-1] != QChar('/')) { + path += QChar('/'); + } +} + +#define SYMBIAN_SDKS_KEY "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs" + +static QString epocRootStr; + +QString epocRoot() +{ + if (!epocRootStr.isEmpty()) { + return epocRootStr; + } + + // First, check the env variable + epocRootStr = qgetenv("EPOCROOT"); + + if (epocRootStr.isEmpty()) { + // No EPOCROOT set, check the default device + // First check EPOCDEVICE env variable + QString defaultDevice = qgetenv("EPOCDEVICE"); + + // Check the windows registry via QSettings for devices.xml path + QSettings settings(SYMBIAN_SDKS_KEY, QSettings::NativeFormat); + QString devicesXmlPath = settings.value("CommonPath").toString(); + + if (!devicesXmlPath.isEmpty()) { + // Parse xml for correct device + devicesXmlPath += "/devices.xml"; + QFile devicesFile(devicesXmlPath); + if (devicesFile.open(QIODevice::ReadOnly)) { + QXmlStreamReader xml(&devicesFile); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "devices") { + if (xml.attributes().value("version") == "1.0") { + // Look for correct device + while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "device") { + if ((defaultDevice.isEmpty() && xml.attributes().value("default") == "yes") || + (!defaultDevice.isEmpty() && (xml.attributes().value("id").toString() + QString(":") + xml.attributes().value("name").toString()) == defaultDevice)) { + // Found the correct device + while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "epocroot") { + epocRootStr = xml.readElementText(); + fixEpocRootStr(epocRootStr); + return epocRootStr; + } + } + xml.raiseError("No epocroot element found"); + } + } + } + } else { + xml.raiseError("Invalid 'devices' element version"); + } + } + } + if (xml.hasError()) { + fprintf(stderr, "ERROR: \"%s\" when parsing devices.xml\n", qPrintable(xml.errorString())); + } + } else { + fprintf(stderr, "Could not open devices.xml (%s)\n", qPrintable(devicesXmlPath)); + } + } else { + fprintf(stderr, "Could not retrieve " SYMBIAN_SDKS_KEY " setting\n"); + } + + fprintf(stderr, "Failed to determine epoc root.\n"); + if (!defaultDevice.isEmpty()) + fprintf(stderr, "The device indicated by EPOCDEVICE environment variable (%s) could not be found.\n", qPrintable(defaultDevice)); + fprintf(stderr, "Either set EPOCROOT or EPOCDEVICE environment variable to a valid value, or provide a default Symbian device.\n"); + + // No valid device found; set epocroot to "/" + epocRootStr = QLatin1String("/"); + } + + fixEpocRootStr(epocRootStr); + return epocRootStr; +} + + static bool isPlugin(const QFileInfo& info, const QString& devicePath) { // Libraries are plugins if deployment path is something else than diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index b409225..e23e6a9 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -50,6 +50,8 @@ #include #include +#include "epocroot.h" + #define PLUGIN_STUB_DIR "qmakepluginstubs" struct CopyItem diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index a712434..2055f81 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -49,9 +49,6 @@ #include #include -// Included from tools/shared -#include - #define RESOURCE_DIRECTORY_MMP "/resource/apps" #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 6c62412..033bcbe 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -48,9 +48,6 @@ #include #include -// Included from tools/shared -#include - #define DO_NOTHING_TARGET "do_nothing" #define CREATE_TEMPS_TARGET "create_temps" #define EXTENSION_CLEAN "extension_clean" diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 8accfce..e081b19 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -48,9 +48,6 @@ #include #include -// Included from tools/shared -#include - SymbianSbsv2MakefileGenerator::SymbianSbsv2MakefileGenerator() : SymbianMakefileGenerator() { } SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { } diff --git a/qmake/project.cpp b/qmake/project.cpp index e4ef7dd..4ce8ba4 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -44,6 +44,8 @@ #include "option.h" #include "cachekeys.h" +#include "epocroot.h" + #include #include #include @@ -62,9 +64,6 @@ #include #include -// Included from tools/shared -#include - #ifdef Q_OS_WIN32 #define QT_POPEN _popen #define QT_PCLOSE _pclose diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 05debe6..a2ffe15 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -18,8 +18,7 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ generators/symbian/initprojectdeploy_symbian.cpp \ - windows/registry.cpp \ - symbian/epocroot.cpp + windows/registry.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -32,8 +31,7 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ generators/symbian/initprojectdeploy_symbian.h \ - windows/registry.h \ - symbian/epocroot.h + windows/registry.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/tools/shared/symbian/epocroot.cpp b/tools/shared/symbian/epocroot.cpp deleted file mode 100644 index 071477d..0000000 --- a/tools/shared/symbian/epocroot.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include - -#include "epocroot.h" -#include "../windows/registry.h" - -// Registry key under which the location of the Symbian devices.xml file is -// stored. -// Note that, on 64-bit machines, this key is located under the 32-bit -// compatibility key: -// HKEY_LOCAL_MACHINE\Software\Wow6432Node -#define SYMBIAN_SDKS_REG_SUBKEY "Software\\Symbian\\EPOC SDKs\\CommonPath" - -#ifdef Q_OS_WIN32 -# define SYMBIAN_SDKS_REG_HANDLE HKEY_LOCAL_MACHINE -#else -# define SYMBIAN_SDKS_REG_HANDLE 0 -#endif - -// Value which is populated and returned by the epocRoot() function. -// Stored as a static value in order to avoid unnecessary re-evaluation. -static QString epocRootValue; - -#ifdef QT_BUILD_QMAKE -std::ostream &operator<<(std::ostream &s, const QString &val) { - s << val.toLocal8Bit().data(); - return s; -} -#else -// Operator implemented in configureapp.cpp -std::ostream &operator<<(std::ostream &s, const QString &val); -#endif - -QString getDevicesXmlPath() - { - // Note that the following call will return a null string on platforms other - // than Windows. If support is required on other platforms for devices.xml, - // an alternative mechanism for retrieving the location of this file will - // be required. - return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY); - } - -/** - * Checks whether epocRootValue points to an existent directory. - * If not, epocRootValue is set to an empty string and an error message is printed. - */ -void checkEpocRootExists(const QString &source) -{ - if (!epocRootValue.isEmpty()) { - QDir dir(epocRootValue); - if (!dir.exists()) { - std::cerr << "Warning: " << source << " is set to an invalid path: " << epocRootValue << std::endl; - epocRootValue = QString(); - } - } -} - -/** - * Translate path from Windows to Qt format. - */ -static void fixEpocRoot(QString &path) -{ - path.replace("\\", "/"); - - if (path.size() > 1 && path[1] == QChar(':')) { - path = path.mid(2); - } - - if (!path.size() || path[path.size()-1] != QChar('/')) { - path += QChar('/'); - } -} - -/** - * Determine the epoc root for the currently active SDK. - */ -QString epocRoot() -{ - if (epocRootValue.isEmpty()) { - // 1. If environment variable EPOCROOT is set and points to an existent - // directory, this is returned. - epocRootValue = qgetenv("EPOCROOT"); - checkEpocRootExists("EPOCROOT"); - - if (epocRootValue.isEmpty()) { - // 2. The location of devices.xml is specified by a registry key. If this - // file exists, it is parsed. - QString devicesXmlPath = getDevicesXmlPath(); - if (devicesXmlPath.isEmpty()) { - std::cerr << "Error: Symbian SDK registry key not found" << std::endl; - } else { - devicesXmlPath += "/devices.xml"; - QFile devicesFile(devicesXmlPath); - if (devicesFile.open(QIODevice::ReadOnly)) { - - // 3. If the EPOCDEVICE environment variable is set and a corresponding - // entry is found in devices.xml, and its epocroot value points to an - // existent directory, it is returned. - // 4. If a device element marked as default is found in devices.xml and its - // epocroot value points to an existent directory, this is returned. - - const QString epocDeviceValue = qgetenv("EPOCDEVICE"); - bool epocDeviceFound = false; - - QXmlStreamReader xml(&devicesFile); - while (!xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "devices") { - if (xml.attributes().value("version") == "1.0") { - while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "device") { - const bool isDefault = xml.attributes().value("default") == "yes"; - const QString id = xml.attributes().value("id").toString(); - const QString name = xml.attributes().value("name").toString(); - const bool epocDeviceMatch = (id + ":" + name) == epocDeviceValue; - epocDeviceFound |= epocDeviceMatch; - - if((epocDeviceValue.isEmpty() && isDefault) || epocDeviceMatch) { - // Found a matching device - while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "epocroot") { - epocRootValue = xml.readElementText(); - const QString deviceSource = epocDeviceValue.isEmpty() - ? "default device" - : "EPOCDEVICE (" + epocDeviceValue + ")"; - checkEpocRootExists(deviceSource); - } - } - - if (epocRootValue.isEmpty()) - xml.raiseError("No epocroot element found"); - } - } - } - } else { - xml.raiseError("Invalid 'devices' element version"); - } - } - } - if (xml.hasError()) { - std::cerr << "Error: \"" << xml.errorString() << "\" when parsing devices.xml" << std::endl; - } else { - if (epocRootValue.isEmpty()) { - if (!epocDeviceValue.isEmpty()) { - if (epocDeviceFound) { - std::cerr << "Error: missing or invalid epocroot attribute " - << "in device '" << epocDeviceValue << "'"; - } else { - std::cerr << "Error: no device matching EPOCDEVICE (" - << epocDeviceValue << ")"; - } - } else { - if (epocDeviceFound) { - std::cerr << "Error: missing or invalid epocroot attribute " - << "in default device"; - } else { - std::cerr << "Error: no default device"; - } - } - std::cerr << " found in devices.xml file." << std::endl; - } - } - } else { - std::cerr << "Error: could not open file " << devicesXmlPath << std::endl; - } - } - } - - if (epocRootValue.isEmpty()) { - // 5. An empty string is returned. - std::cerr << "Error: failed to find epoc root" << std::endl - << "Either" << std::endl - << " 1. Set EPOCROOT environment variable to a valid value" << std::endl - << " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY - " registry key is set, and then" << std::endl - << " a. Set EPOCDEVICE environment variable to a valid device" << std::endl - << " or b. Specify a default device in the devices.xml file." << std::endl; - } else { - fixEpocRoot(epocRootValue); - } - } - - return epocRootValue; -} - diff --git a/tools/shared/symbian/epocroot.h b/tools/shared/symbian/epocroot.h deleted file mode 100644 index 9846485..0000000 --- a/tools/shared/symbian/epocroot.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SYMBIAN_EPOCROOT_H -#define SYMBIAN_EPOCROOT_H - -#include - -/** - * Determine the epoc root for the currently active SDK. - * - * The algorithm used is as follows: - * 1. If environment variable EPOCROOT is set and points to an existent - * directory, this is returned. - * 2. The location of devices.xml is specified by a registry key. If this - * file exists, it is parsed. - * 3. If the EPOCDEVICE environment variable is set and a corresponding - * entry is found in devices.xml, and its epocroot value points to an - * existent directory, it is returned. - * 4. If a device element marked as default is found in devices.xml and its - * epocroot value points to an existent directory, this is returned. - * 5. An empty string is returned. - * - * Any return value other than the empty string therefore is guaranteed to - * point to an existent directory. - */ -QString epocRoot(); - -#endif // EPOCROOT_H -- cgit v0.12 From f5309598ddb3bf0f9e3bc182e78f1b2062540c98 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 19 Feb 2010 09:56:47 +0100 Subject: Revert "Factored readRegistryKey implementation out of qmake" This reverts commit f641369ceb7b7e2f95b9d0656b34c0517c5b95f7. It breaks non-Symbian platforms. --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 7 -- qmake/Makefile.win32-g++ | 5 - qmake/Makefile.win32-g++-sh | 5 - qmake/generators/win32/msvc_vcproj.cpp | 97 +++++++++++++++++++- qmake/qmake.pri | 7 +- qmake/qmake.pro | 4 - tools/shared/windows/registry.cpp | 161 --------------------------------- tools/shared/windows/registry.h | 64 ------------- 9 files changed, 100 insertions(+), 259 deletions(-) delete mode 100644 tools/shared/windows/registry.cpp delete mode 100644 tools/shared/windows/registry.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index e343803..fcf43c8 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -10,8 +10,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ mingw_make.o option.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ - symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o + symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -21,7 +20,6 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ - registry.o \ $(QTOBJS) @@ -34,7 +32,6 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/makefiledeps.cpp option.cpp generators/win32/mingw_make.cpp generators/makefile.cpp \ generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ - $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -65,7 +62,6 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \ -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \ -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \ - -I$(BUILD_PATH)/tools/shared \ -DQT_NO_PCRE \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \ @@ -285,9 +281,6 @@ symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp -registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp - projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 3cd180c..e6bbcd5 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -34,7 +34,6 @@ CFLAGS = -c -Fo$@ \ -I$(BUILD_PATH)\src\corelib\global \ -I$(BUILD_PATH)\src\corelib\xml \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ - -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \ @@ -60,7 +59,6 @@ CFLAGS = -c -o$@ \ -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \ -I$(BUILD_PATH)\src\corelib\global \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ - -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT @@ -77,7 +75,6 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ - registry.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -201,7 +198,6 @@ clean:: -del symmake_abld.obj -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj - -del registry.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -401,9 +397,6 @@ symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp -registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp - md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ebc7fe2..ade379b 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -21,7 +21,6 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ - -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -39,7 +38,6 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -280,9 +278,6 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp -registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp - project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 1d55da2..8d2723c 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -21,7 +21,6 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ - -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -39,7 +38,6 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -279,9 +277,6 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp -registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp - project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 58f95e9..47986f5 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -67,7 +67,6 @@ QT_END_NAMESPACE #ifdef Q_OS_WIN32 #include -#include QT_BEGIN_NAMESPACE @@ -94,6 +93,102 @@ struct { {NETUnknown, "", ""}, }; +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == "Default" || res == ".") + res = ""; + return res; +} + +static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) +{ + + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = 0; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + QString result; + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(", "); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %d type in windows registry", dataType); + break; + } + + RegCloseKey(handle); + return result; +} QT_END_NAMESPACE #endif diff --git a/qmake/qmake.pri b/qmake/qmake.pri index a2ffe15..efe4f36 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -17,8 +17,7 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ - generators/symbian/initprojectdeploy_symbian.cpp \ - windows/registry.cpp + generators/symbian/initprojectdeploy_symbian.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -30,8 +29,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ - generators/symbian/initprojectdeploy_symbian.h \ - windows/registry.h + generators/symbian/epocroot.h \ + generators/symbian/initprojectdeploy_symbian.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/qmake/qmake.pro b/qmake/qmake.pro index f3f9d53..00dcbce 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -27,9 +27,5 @@ INCPATH += generators \ $$QT_SOURCE_TREE/include \ $$QT_SOURCE_TREE/include/QtCore \ $$QT_SOURCE_TREE/qmake - -VPATH += $$QT_SOURCE_TREE/tools/shared -INCPATH += $$QT_SOURCE_TREE/tools/shared - include(qmake.pri) diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp deleted file mode 100644 index d342d78..0000000 --- a/tools/shared/windows/registry.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "registry.h" - -/*! - Returns the path part of a registry key. - e.g. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" -*/ -static QString keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -/*! - Returns the name part of a registry key. - e.g. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "ProductDir" -*/ -static QString keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == "Default" || res == ".") - res = ""; - return res; -} - -QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) -{ - QString result; - -#ifdef Q_OS_WIN32 - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = 0; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); - - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(", "); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); - break; - } - - RegCloseKey(handle); -#endif - - return result; -} - - diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry.h deleted file mode 100644 index 3896527..0000000 --- a/tools/shared/windows/registry.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WINDOWS_REGISTRY_H -#define WINDOWS_REGISTRY_H - -#include - -#ifdef Q_OS_WIN32 - #include -#else - typedef void* HKEY; -#endif - -#include - -/** - * Read a value from the Windows registry. - * - * If the key is not found, or the registry cannot be accessed (for example - * if this code is compiled for a platform other than Windows), a null - * string is returned. - */ -QString readRegistryKey(HKEY parentHandle, const QString &rSubkey); - -#endif // WINDOWS_REGISTRY_H -- cgit v0.12 From 868a8d5d80f9e455e68c71522c6a710345c2d9fa Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 19 Feb 2010 10:58:13 +0200 Subject: Virtual keyboard can't be closed anymore after tapping the text area On Symbian^3, the virtual keyboard cannot be closed anymore when the editor area where the text is displayed is tapped and autocompletion is suggesting a word currently. This is caused by the fragile native FEP manager which assumes that client must report certain event (EAknCursorPositionChanged), after user interaction with the editor area. Otherwise the native FEP manager is in dead-lock, until somebody reports this event to it. Task-number: QTBUG-7828 Reviewed-by: axis --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 2b91711..1ac8ace 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -113,7 +113,7 @@ void QCoeFepInputContext::update() updateHints(false); // For pre-5.0 SDKs, we don't do text updates on S60 side. - if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) { + if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_0) { return; } @@ -740,6 +740,9 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin void QCoeFepInputContext::DoCommitFepInlineEditL() { commitCurrentString(false); + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) + ReportAknEdStateEvent(QT_EAknCursorPositionChanged); + } void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction) -- cgit v0.12 From db0057534835356f5c471f3e0f32fad30e32becb Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 19 Feb 2010 11:43:35 +0200 Subject: ColorDialog is always shown as stripped-down version (for QVGA) QColorDialog creates own instance of S60Data and fetches touch support value from that. Unfortunately, newly created S60Data is populated with default values that claim no support for touch. As a fix, QColorDialog uses the global variable "S60" to fetch touch support information. Task-number: QTBUG-8322 Reviewed-by: Shane Kearns --- src/gui/dialogs/qcolordialog.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp index 83ecc30..e6abf7f 100644 --- a/src/gui/dialogs/qcolordialog.cpp +++ b/src/gui/dialogs/qcolordialog.cpp @@ -1078,8 +1078,7 @@ QColorShower::QColorShower(QColorDialog *parent) #ifdef QT_SMALL_COLORDIALOG # ifdef Q_WS_S60 - QS60Data s60Data = QS60Data(); - const bool nonTouchUI = !s60Data.hasTouchscreen; + const bool nonTouchUI = !S60->hasTouchscreen; # elif defined Q_WS_MAEMO_5 const bool nonTouchUI = false; # endif @@ -1506,8 +1505,7 @@ void QColorDialogPrivate::init(const QColor &initial) #if defined(QT_SMALL_COLORDIALOG) # if defined(Q_WS_S60) - QS60Data s60Data = QS60Data(); - const bool nonTouchUI = !s60Data.hasTouchscreen; + const bool nonTouchUI = !S60->hasTouchscreen; # elif defined(Q_WS_MAEMO_5) const bool nonTouchUI = false; # endif -- cgit v0.12 From 254676322463778319e4a1b572d6c76f9c256393 Mon Sep 17 00:00:00 2001 From: ninerider Date: Fri, 19 Feb 2010 10:48:27 +0100 Subject: Remote lib extensions for Windows Mobile device power operations. Function to change the power mode and to reset the device were added. The reset is needed to put the device in a defined state after an error has occurred. The unattended power mode ensures that the reset can be effected and that the device will not go to sleep. Reviewed by: Joerg --- tools/qtestlib/wince/remotelib/commands.cpp | 86 +++++++++++++++++++++++++++++ tools/qtestlib/wince/remotelib/commands.h | 3 + 2 files changed, 89 insertions(+) diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp index 4244424..88bf9e6 100644 --- a/tools/qtestlib/wince/remotelib/commands.cpp +++ b/tools/qtestlib/wince/remotelib/commands.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ #include "commands.h" +#include +#include + #define CLEAN_FAIL(a) {delete appName; \ delete arguments; \ @@ -124,3 +127,86 @@ bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *retur } return true; } +/** +\brief Reset the device. +*/ +int qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + //POWER_STATE_ON On state + //POWER_STATE_OFF Off state + //POWER_STATE_CRITICAL Critical state + //POWER_STATE_BOOT Boot state + //POWER_STATE_IDLE Idle state + //POWER_STATE_SUSPEND Suspend state + //POWER_STATE_RESET Reset state + + DWORD returnValue = SetSystemPowerState(0, POWER_STATE_RESET, POWER_FORCE); + return returnValue; +} + +/** +\brief Toggle the unattended powermode of the device +*/ +int qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + if (!stream) + return -1; + + DWORD bytesRead; + int toggleVal = 0; + int returnValue = S_OK; + + if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) + return -2; + + //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). + //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). + //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. + //PPN_SUSPENDKEYPRESSED or + //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). + //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). + //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). + //PPN_OEMBASE Greater than or equal to 0x10000 + //You can define higher values, such as 0x10001, 0x10002, and so on. + // Reserved. Set dwData to zero (0). + returnValue = PowerPolicyNotify(PPN_UNATTENDEDMODE, toggleVal); + + if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) + return -3; + else + return S_OK; +} + +/** +\brief Virtually press the power button of the device +*/ +int qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + if (!stream) + return -1; + + DWORD bytesRead; + int toggleVal = 0; + int returnValue = S_OK; + + if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) + return -2; + + //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). + //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). + //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. + //PPN_SUSPENDKEYPRESSED or + //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). + //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). + //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). + //PPN_OEMBASE Greater than or equal to 0x10000 + //You can define higher values, such as 0x10001, 0x10002, and so on. + // Reserved. Set dwData to zero (0). + returnValue = PowerPolicyNotify(PPN_POWERBUTTONPRESSED, 0); + + if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) + return -3; + else + return S_OK; +} + diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h index c5cc926..8f202c8 100644 --- a/tools/qtestlib/wince/remotelib/commands.h +++ b/tools/qtestlib/wince/remotelib/commands.h @@ -45,6 +45,9 @@ extern "C" { int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); + int __declspec(dllexport) qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); + int __declspec(dllexport) qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); + int __declspec(dllexport) qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); } -- cgit v0.12 From 1d75abb9a481b058f5251b83446aa0e171217786 Mon Sep 17 00:00:00 2001 From: ninerider Date: Fri, 19 Feb 2010 10:50:47 +0100 Subject: Cetest extensions for Windows Mobile device power operations. Options to reset (-reset) and change the power mode (-wake) of the device were added. The reset is needed to put the device in a defined state after an error has occurred. The unattended power mode ensures that the reset can be effected and that the device will not go to sleep. Reviewed by: Joerg --- .../qtestlib/wince/cetest/activesyncconnection.cpp | 139 +++++++++++++++++++++ tools/qtestlib/wince/cetest/activesyncconnection.h | 3 + tools/qtestlib/wince/cetest/main.cpp | 48 +++++++ 3 files changed, 190 insertions(+) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 56fb173..98062ed 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -443,6 +443,145 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo return result; } +bool ActiveSyncConnection::setDeviceAwake(bool activate, int *returnValue) +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + bool result = false; + + // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait + // until the process ends. The lib must have been build and also deployed already. + if (!isConnected() && !connect()) + return false; + + HRESULT res = S_OK; + + //SYSTEM_POWER_STATUS_EX systemPowerState; + + //res = CeGetSystemPowerStatusEx(&systemPowerState, true); + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemoteToggleUnattendedPowerMode"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + int returned = 0; + int toggle = int(activate); + + res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + DWORD written; + + if (S_OK != stream->Write(&toggle, sizeof(toggle), &written)) { + qWarning(" Could not write toggle option to process"); + return false; + } + + if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { + qWarning(" Could not access return value of process"); + } + else + result = true; + } + + if (returnValue) + *returnValue = returned; + + return result; +} + +bool ActiveSyncConnection::resetDevice() +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + + bool result = false; + if (!isConnected() && !connect()) + return false; + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemoteSoftReset"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + + int returned = 0; + + HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + result = true; + } + return result; +} + +bool ActiveSyncConnection::toggleDevicePower(int *returnValue) +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + + bool result = false; + if (!isConnected() && !connect()) + return false; + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemotePowerButton"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + int returned = 0; + + HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + DWORD written; + if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { + qWarning(" Could not access return value of process"); + } + else { + result = true; + } + } + + if (returnValue) + *returnValue = returned; + return result; +} + bool ActiveSyncConnection::createDirectory(const QString &path, bool deleteBefore) { if (deleteBefore) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.h b/tools/qtestlib/wince/cetest/activesyncconnection.h index 1891514..4502fc7 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.h +++ b/tools/qtestlib/wince/cetest/activesyncconnection.h @@ -79,6 +79,9 @@ public: bool createDirectory(const QString&, bool deleteBefore=false); bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); + bool resetDevice(); + bool toggleDevicePower(int *returnValue = NULL); + bool setDeviceAwake(bool activate, int *returnValue = NULL); private: bool connected; }; diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index 146cc5a..9fe5f02 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -45,6 +45,9 @@ # include "activesyncconnection.h" #endif +const int SLEEP_AFTER_RESET = 60000; // sleep for 1 minute +const int SLEEP_RECONNECT = 2000; // sleep for 2 seconds before trying another reconnect + #include "deployment.h" #include #include @@ -123,6 +126,8 @@ void usage() " -debug : Test debug version[default]\n" " -release : Test release version\n" " -libpath : Remote path to deploy Qt libraries to\n" + " -reset : Reset device before starting a test\n" + " -awake : Device does not go sleep mode\n" " -qt-delete : Delete the Qt libraries after execution\n" " -project-delete : Delete the project file(s) after execution\n" " -delete : Delete everything deployed after execution\n" @@ -152,6 +157,8 @@ int main(int argc, char **argv) int timeout = -1; bool cleanupQt = false; bool cleanupProject = false; + bool deviceReset = false; + bool keepAwake = false; for (int i=1; i Date: Wed, 10 Feb 2010 13:20:09 +0000 Subject: Factored readRegistryKey implementation out of qmake This function is now implemented with its own header and source files, rather than being embedded within the MSVC qmake generator. The motivation for this is to allow code to be shared between qmake and configure, both of which query the registry when built for Windows. Reviewed-by: Miikka Heikkinen --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 7 ++ qmake/Makefile.win32-g++ | 5 + qmake/Makefile.win32-g++-sh | 5 + qmake/generators/win32/msvc_vcproj.cpp | 97 +------------------- qmake/qmake.pri | 7 +- qmake/qmake.pro | 4 + tools/shared/windows/registry.cpp | 161 +++++++++++++++++++++++++++++++++ tools/shared/windows/registry.h | 64 +++++++++++++ 9 files changed, 259 insertions(+), 100 deletions(-) create mode 100644 tools/shared/windows/registry.cpp create mode 100644 tools/shared/windows/registry.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index fcf43c8..e343803 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -10,7 +10,8 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ mingw_make.o option.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ - symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o + symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ + registry.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -20,6 +21,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ + registry.o \ $(QTOBJS) @@ -32,6 +34,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/makefiledeps.cpp option.cpp generators/win32/mingw_make.cpp generators/makefile.cpp \ generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ + $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -62,6 +65,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \ -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \ -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \ + -I$(BUILD_PATH)/tools/shared \ -DQT_NO_PCRE \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \ @@ -281,6 +285,9 @@ symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index e6bbcd5..3cd180c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -34,6 +34,7 @@ CFLAGS = -c -Fo$@ \ -I$(BUILD_PATH)\src\corelib\global \ -I$(BUILD_PATH)\src\corelib\xml \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED \ @@ -59,6 +60,7 @@ CFLAGS = -c -o$@ \ -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \ -I$(BUILD_PATH)\src\corelib\global \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ + -I$(SOURCE_PATH)\tools\shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \ -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD \ -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT @@ -75,6 +77,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ + registry.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -198,6 +201,7 @@ clean:: -del symmake_abld.obj -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj + -del registry.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -397,6 +401,9 @@ symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ade379b..ebc7fe2 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -278,6 +280,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 8d2723c..1d55da2 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -21,6 +21,7 @@ CFLAGS = -c -o$@ -O \ -I$(BUILD_PATH)/src/corelib/global \ -I$(BUILD_PATH)/src/corelib/xml \ -I$(SOURCE_PATH)/mkspecs/win32-g++ \ + -I$(SOURCE_PATH)/tools/shared \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_PCRE \ -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -38,6 +39,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ + registry.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -277,6 +279,9 @@ symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp +registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 47986f5..58f95e9 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -67,6 +67,7 @@ QT_END_NAMESPACE #ifdef Q_OS_WIN32 #include +#include QT_BEGIN_NAMESPACE @@ -93,102 +94,6 @@ struct { {NETUnknown, "", ""}, }; -static QString keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -static QString keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == "Default" || res == ".") - res = ""; - return res; -} - -static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) -{ - - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = 0; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); - - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - QString result; - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(", "); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %d type in windows registry", dataType); - break; - } - - RegCloseKey(handle); - return result; -} QT_END_NAMESPACE #endif diff --git a/qmake/qmake.pri b/qmake/qmake.pri index efe4f36..a2ffe15 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -17,7 +17,8 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ - generators/symbian/initprojectdeploy_symbian.cpp + generators/symbian/initprojectdeploy_symbian.cpp \ + windows/registry.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -29,8 +30,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ - generators/symbian/epocroot.h \ - generators/symbian/initprojectdeploy_symbian.h + generators/symbian/initprojectdeploy_symbian.h \ + windows/registry.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 00dcbce..f3f9d53 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -27,5 +27,9 @@ INCPATH += generators \ $$QT_SOURCE_TREE/include \ $$QT_SOURCE_TREE/include/QtCore \ $$QT_SOURCE_TREE/qmake + +VPATH += $$QT_SOURCE_TREE/tools/shared +INCPATH += $$QT_SOURCE_TREE/tools/shared + include(qmake.pri) diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp new file mode 100644 index 0000000..d342d78 --- /dev/null +++ b/tools/shared/windows/registry.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "registry.h" + +/*! + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/*! + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == "Default" || res == ".") + res = ""; + return res; +} + +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = 0; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(", "); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %d type in windows registry", dataType); + break; + } + + RegCloseKey(handle); +#endif + + return result; +} + + diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry.h new file mode 100644 index 0000000..3896527 --- /dev/null +++ b/tools/shared/windows/registry.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWS_REGISTRY_H +#define WINDOWS_REGISTRY_H + +#include + +#ifdef Q_OS_WIN32 + #include +#else + typedef void* HKEY; +#endif + +#include + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + */ +QString readRegistryKey(HKEY parentHandle, const QString &rSubkey); + +#endif // WINDOWS_REGISTRY_H -- cgit v0.12 From 6ebcf2c24b43fdc1d6da50e9d7ec9dd63dd507d7 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 10 Feb 2010 14:57:51 +0000 Subject: Factored epocRoot implementation out of qmake This function is now implemented in its own source file, rather than being embedded within the Symbian qmake generator. The motivation for this is to allow code to be shared between qmake and configure - the latter needs to determine the epoc root path in order to perform feature detection on Symbian SDKs. Reviewed-by: Miikka Heikkinen --- qmake/Makefile.unix | 9 +- qmake/Makefile.win32 | 5 + qmake/Makefile.win32-g++ | 4 + qmake/Makefile.win32-g++-sh | 4 + qmake/generators/symbian/epocroot.h | 51 ----- .../symbian/initprojectdeploy_symbian.cpp | 96 +-------- .../generators/symbian/initprojectdeploy_symbian.h | 2 - qmake/generators/symbian/symmake.cpp | 3 + qmake/generators/symbian/symmake_abld.cpp | 3 + qmake/generators/symbian/symmake_sbsv2.cpp | 3 + qmake/project.cpp | 5 +- qmake/qmake.pri | 6 +- tools/shared/symbian/epocroot.cpp | 230 +++++++++++++++++++++ tools/shared/symbian/epocroot.h | 67 ++++++ 14 files changed, 337 insertions(+), 151 deletions(-) delete mode 100644 qmake/generators/symbian/epocroot.h create mode 100644 tools/shared/symbian/epocroot.cpp create mode 100644 tools/shared/symbian/epocroot.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index e343803..5469134 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -11,7 +11,8 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o + registry.o \ + epocroot.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -22,6 +23,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ registry.o \ + epocroot.o \ $(QTOBJS) @@ -35,6 +37,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge generators/win32/msvc_objectmodel.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ generators/symbian/symmake.cpp generators/symbian/initprojectdeploy_symbian.cpp \ $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ + $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ @@ -288,6 +291,9 @@ initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp @@ -296,6 +302,7 @@ qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp + #default rules .cpp.o: $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 3cd180c..48d84b7 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -78,6 +78,7 @@ OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ registry.obj \ + epocroot.obj \ symmake_abld.obj symmake_sbsv2.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -202,6 +203,7 @@ clean:: -del symmake_sbsv2.obj -del initprojectdeploy_symbian.obj -del registry.obj + -del epocroot.obj -del pbuilder_pbx.obj -del qxmlstream.obj -del qxmlutils.obj @@ -404,6 +406,9 @@ initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initproje registry.obj: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.obj: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + md5.obj: $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\3rdparty\md5\md5.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index ebc7fe2..169de3c 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -40,6 +40,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ + epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -283,6 +284,9 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 1d55da2..98237e7 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -40,6 +40,7 @@ OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ registry.o \ + epocroot.o \ symmake_abld.o symmake_sbsv2.o ifdef QMAKE_OPENSOURCE_EDITION @@ -282,6 +283,9 @@ initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initproject registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +epocroot.o: $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp + project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h $(CXX) $(CXXFLAGS) project.cpp diff --git a/qmake/generators/symbian/epocroot.h b/qmake/generators/symbian/epocroot.h deleted file mode 100644 index be26438..0000000 --- a/qmake/generators/symbian/epocroot.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef EPOCROOT_H -#define EPOCROOT_H - -#include - -// Implementation of epocRoot method is in initprojectdeploy_symbian.cpp -// Defined in separate header for inclusion clarity -extern QString epocRoot(); - -#endif // EPOCROOT_H diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 5fbff58..2a22305 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -46,105 +46,15 @@ #include #include +// Included from tools/shared +#include + #define SYSBIN_DIR "\\sys\\bin" #define SUFFIX_DLL "dll" #define SUFFIX_EXE "exe" #define SUFFIX_QTPLUGIN "qtplugin" -static void fixEpocRootStr(QString& path) -{ - path.replace("\\", "/"); - - if (path.size() > 1 && path[1] == QChar(':')) { - path = path.mid(2); - } - - if (!path.size() || path[path.size()-1] != QChar('/')) { - path += QChar('/'); - } -} - -#define SYMBIAN_SDKS_KEY "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs" - -static QString epocRootStr; - -QString epocRoot() -{ - if (!epocRootStr.isEmpty()) { - return epocRootStr; - } - - // First, check the env variable - epocRootStr = qgetenv("EPOCROOT"); - - if (epocRootStr.isEmpty()) { - // No EPOCROOT set, check the default device - // First check EPOCDEVICE env variable - QString defaultDevice = qgetenv("EPOCDEVICE"); - - // Check the windows registry via QSettings for devices.xml path - QSettings settings(SYMBIAN_SDKS_KEY, QSettings::NativeFormat); - QString devicesXmlPath = settings.value("CommonPath").toString(); - - if (!devicesXmlPath.isEmpty()) { - // Parse xml for correct device - devicesXmlPath += "/devices.xml"; - QFile devicesFile(devicesXmlPath); - if (devicesFile.open(QIODevice::ReadOnly)) { - QXmlStreamReader xml(&devicesFile); - while (!xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "devices") { - if (xml.attributes().value("version") == "1.0") { - // Look for correct device - while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "device") { - if ((defaultDevice.isEmpty() && xml.attributes().value("default") == "yes") || - (!defaultDevice.isEmpty() && (xml.attributes().value("id").toString() + QString(":") + xml.attributes().value("name").toString()) == defaultDevice)) { - // Found the correct device - while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement() && xml.name() == "epocroot") { - epocRootStr = xml.readElementText(); - fixEpocRootStr(epocRootStr); - return epocRootStr; - } - } - xml.raiseError("No epocroot element found"); - } - } - } - } else { - xml.raiseError("Invalid 'devices' element version"); - } - } - } - if (xml.hasError()) { - fprintf(stderr, "ERROR: \"%s\" when parsing devices.xml\n", qPrintable(xml.errorString())); - } - } else { - fprintf(stderr, "Could not open devices.xml (%s)\n", qPrintable(devicesXmlPath)); - } - } else { - fprintf(stderr, "Could not retrieve " SYMBIAN_SDKS_KEY " setting\n"); - } - - fprintf(stderr, "Failed to determine epoc root.\n"); - if (!defaultDevice.isEmpty()) - fprintf(stderr, "The device indicated by EPOCDEVICE environment variable (%s) could not be found.\n", qPrintable(defaultDevice)); - fprintf(stderr, "Either set EPOCROOT or EPOCDEVICE environment variable to a valid value, or provide a default Symbian device.\n"); - - // No valid device found; set epocroot to "/" - epocRootStr = QLatin1String("/"); - } - - fixEpocRootStr(epocRootStr); - return epocRootStr; -} - - static bool isPlugin(const QFileInfo& info, const QString& devicePath) { // Libraries are plugins if deployment path is something else than diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index e23e6a9..b409225 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -50,8 +50,6 @@ #include #include -#include "epocroot.h" - #define PLUGIN_STUB_DIR "qmakepluginstubs" struct CopyItem diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 2055f81..a712434 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -49,6 +49,9 @@ #include #include +// Included from tools/shared +#include + #define RESOURCE_DIRECTORY_MMP "/resource/apps" #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 033bcbe..6c62412 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -48,6 +48,9 @@ #include #include +// Included from tools/shared +#include + #define DO_NOTHING_TARGET "do_nothing" #define CREATE_TEMPS_TARGET "create_temps" #define EXTENSION_CLEAN "extension_clean" diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index e081b19..8accfce 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -48,6 +48,9 @@ #include #include +// Included from tools/shared +#include + SymbianSbsv2MakefileGenerator::SymbianSbsv2MakefileGenerator() : SymbianMakefileGenerator() { } SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { } diff --git a/qmake/project.cpp b/qmake/project.cpp index 4ce8ba4..e4ef7dd 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -44,8 +44,6 @@ #include "option.h" #include "cachekeys.h" -#include "epocroot.h" - #include #include #include @@ -64,6 +62,9 @@ #include #include +// Included from tools/shared +#include + #ifdef Q_OS_WIN32 #define QT_POPEN _popen #define QT_PCLOSE _pclose diff --git a/qmake/qmake.pri b/qmake/qmake.pri index a2ffe15..05debe6 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -18,7 +18,8 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/symbian/symmake_abld.cpp \ generators/symbian/symmake_sbsv2.cpp \ generators/symbian/initprojectdeploy_symbian.cpp \ - windows/registry.cpp + windows/registry.cpp \ + symbian/epocroot.cpp HEADERS += project.h property.h generators/makefile.h \ generators/unix/unixmake.h meta.h option.h cachekeys.h \ @@ -31,7 +32,8 @@ HEADERS += project.h property.h generators/makefile.h \ generators/symbian/symmake_abld.h \ generators/symbian/symmake_sbsv2.h \ generators/symbian/initprojectdeploy_symbian.h \ - windows/registry.h + windows/registry.h \ + symbian/epocroot.h contains(QT_EDITION, OpenSource) { DEFINES += QMAKE_OPENSOURCE_EDITION diff --git a/tools/shared/symbian/epocroot.cpp b/tools/shared/symbian/epocroot.cpp new file mode 100644 index 0000000..071477d --- /dev/null +++ b/tools/shared/symbian/epocroot.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +#include "epocroot.h" +#include "../windows/registry.h" + +// Registry key under which the location of the Symbian devices.xml file is +// stored. +// Note that, on 64-bit machines, this key is located under the 32-bit +// compatibility key: +// HKEY_LOCAL_MACHINE\Software\Wow6432Node +#define SYMBIAN_SDKS_REG_SUBKEY "Software\\Symbian\\EPOC SDKs\\CommonPath" + +#ifdef Q_OS_WIN32 +# define SYMBIAN_SDKS_REG_HANDLE HKEY_LOCAL_MACHINE +#else +# define SYMBIAN_SDKS_REG_HANDLE 0 +#endif + +// Value which is populated and returned by the epocRoot() function. +// Stored as a static value in order to avoid unnecessary re-evaluation. +static QString epocRootValue; + +#ifdef QT_BUILD_QMAKE +std::ostream &operator<<(std::ostream &s, const QString &val) { + s << val.toLocal8Bit().data(); + return s; +} +#else +// Operator implemented in configureapp.cpp +std::ostream &operator<<(std::ostream &s, const QString &val); +#endif + +QString getDevicesXmlPath() + { + // Note that the following call will return a null string on platforms other + // than Windows. If support is required on other platforms for devices.xml, + // an alternative mechanism for retrieving the location of this file will + // be required. + return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY); + } + +/** + * Checks whether epocRootValue points to an existent directory. + * If not, epocRootValue is set to an empty string and an error message is printed. + */ +void checkEpocRootExists(const QString &source) +{ + if (!epocRootValue.isEmpty()) { + QDir dir(epocRootValue); + if (!dir.exists()) { + std::cerr << "Warning: " << source << " is set to an invalid path: " << epocRootValue << std::endl; + epocRootValue = QString(); + } + } +} + +/** + * Translate path from Windows to Qt format. + */ +static void fixEpocRoot(QString &path) +{ + path.replace("\\", "/"); + + if (path.size() > 1 && path[1] == QChar(':')) { + path = path.mid(2); + } + + if (!path.size() || path[path.size()-1] != QChar('/')) { + path += QChar('/'); + } +} + +/** + * Determine the epoc root for the currently active SDK. + */ +QString epocRoot() +{ + if (epocRootValue.isEmpty()) { + // 1. If environment variable EPOCROOT is set and points to an existent + // directory, this is returned. + epocRootValue = qgetenv("EPOCROOT"); + checkEpocRootExists("EPOCROOT"); + + if (epocRootValue.isEmpty()) { + // 2. The location of devices.xml is specified by a registry key. If this + // file exists, it is parsed. + QString devicesXmlPath = getDevicesXmlPath(); + if (devicesXmlPath.isEmpty()) { + std::cerr << "Error: Symbian SDK registry key not found" << std::endl; + } else { + devicesXmlPath += "/devices.xml"; + QFile devicesFile(devicesXmlPath); + if (devicesFile.open(QIODevice::ReadOnly)) { + + // 3. If the EPOCDEVICE environment variable is set and a corresponding + // entry is found in devices.xml, and its epocroot value points to an + // existent directory, it is returned. + // 4. If a device element marked as default is found in devices.xml and its + // epocroot value points to an existent directory, this is returned. + + const QString epocDeviceValue = qgetenv("EPOCDEVICE"); + bool epocDeviceFound = false; + + QXmlStreamReader xml(&devicesFile); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "devices") { + if (xml.attributes().value("version") == "1.0") { + while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "device") { + const bool isDefault = xml.attributes().value("default") == "yes"; + const QString id = xml.attributes().value("id").toString(); + const QString name = xml.attributes().value("name").toString(); + const bool epocDeviceMatch = (id + ":" + name) == epocDeviceValue; + epocDeviceFound |= epocDeviceMatch; + + if((epocDeviceValue.isEmpty() && isDefault) || epocDeviceMatch) { + // Found a matching device + while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "epocroot") { + epocRootValue = xml.readElementText(); + const QString deviceSource = epocDeviceValue.isEmpty() + ? "default device" + : "EPOCDEVICE (" + epocDeviceValue + ")"; + checkEpocRootExists(deviceSource); + } + } + + if (epocRootValue.isEmpty()) + xml.raiseError("No epocroot element found"); + } + } + } + } else { + xml.raiseError("Invalid 'devices' element version"); + } + } + } + if (xml.hasError()) { + std::cerr << "Error: \"" << xml.errorString() << "\" when parsing devices.xml" << std::endl; + } else { + if (epocRootValue.isEmpty()) { + if (!epocDeviceValue.isEmpty()) { + if (epocDeviceFound) { + std::cerr << "Error: missing or invalid epocroot attribute " + << "in device '" << epocDeviceValue << "'"; + } else { + std::cerr << "Error: no device matching EPOCDEVICE (" + << epocDeviceValue << ")"; + } + } else { + if (epocDeviceFound) { + std::cerr << "Error: missing or invalid epocroot attribute " + << "in default device"; + } else { + std::cerr << "Error: no default device"; + } + } + std::cerr << " found in devices.xml file." << std::endl; + } + } + } else { + std::cerr << "Error: could not open file " << devicesXmlPath << std::endl; + } + } + } + + if (epocRootValue.isEmpty()) { + // 5. An empty string is returned. + std::cerr << "Error: failed to find epoc root" << std::endl + << "Either" << std::endl + << " 1. Set EPOCROOT environment variable to a valid value" << std::endl + << " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY + " registry key is set, and then" << std::endl + << " a. Set EPOCDEVICE environment variable to a valid device" << std::endl + << " or b. Specify a default device in the devices.xml file." << std::endl; + } else { + fixEpocRoot(epocRootValue); + } + } + + return epocRootValue; +} + diff --git a/tools/shared/symbian/epocroot.h b/tools/shared/symbian/epocroot.h new file mode 100644 index 0000000..9846485 --- /dev/null +++ b/tools/shared/symbian/epocroot.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIAN_EPOCROOT_H +#define SYMBIAN_EPOCROOT_H + +#include + +/** + * Determine the epoc root for the currently active SDK. + * + * The algorithm used is as follows: + * 1. If environment variable EPOCROOT is set and points to an existent + * directory, this is returned. + * 2. The location of devices.xml is specified by a registry key. If this + * file exists, it is parsed. + * 3. If the EPOCDEVICE environment variable is set and a corresponding + * entry is found in devices.xml, and its epocroot value points to an + * existent directory, it is returned. + * 4. If a device element marked as default is found in devices.xml and its + * epocroot value points to an existent directory, this is returned. + * 5. An empty string is returned. + * + * Any return value other than the empty string therefore is guaranteed to + * point to an existent directory. + */ +QString epocRoot(); + +#endif // EPOCROOT_H -- cgit v0.12 From 480f3df2eab9ad13e0d7ea1245158866a0b942bd Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 19 Feb 2010 11:16:34 +0100 Subject: Fixed linkage failure when building qmake on Unix platforms Commits f641369c/5254184c and 13cb80be/6ebcf2c2 caused registry.o and epocroot.o respectively to be included twice during the linkage step of qmake/Makefile.unix. --- qmake/Makefile.unix | 2 -- 1 file changed, 2 deletions(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 5469134..fa98fd6 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -22,8 +22,6 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ - registry.o \ - epocroot.o \ $(QTOBJS) -- cgit v0.12 From 1f56953fca1a38b31734ce8a87c01c85f1f0f901 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 19 Feb 2010 12:38:30 +0200 Subject: Fixed libstdcpp.dll version autodetection for Symbian Libstdcpp.dll version autodetection was broken for clean builds, so made it default for new version when neither new or old can be detected. Task-number: QT-1171 Reviewed-by: Janne Anttila --- mkspecs/features/symbian/stl.prf | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/symbian/stl.prf b/mkspecs/features/symbian/stl.prf index e21ee5c..85c758a 100644 --- a/mkspecs/features/symbian/stl.prf +++ b/mkspecs/features/symbian/stl.prf @@ -15,11 +15,18 @@ INCLUDEPATH += $$OS_LAYER_STDCPP_SYSTEMINCLUDE INCLUDEPATH -= $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/stl-off # libstdcppv5 is preferred over libstdcpp as it has/uses the throwing version of operator new -exists($${EPOCROOT}epoc32/release/armv5/urel/libstdcppv5.dll)|exists($${EPOCROOT}epoc32/release/winscw/udeb/libstdcppv5.dll) { - LIBS *= -llibstdcppv5.dll +STL_LIB = -llibstdcppv5.dll - # STDCPP turns on standard C++ new behaviour (ie. throwing new) - MMP_RULES += "STDCPP" -} else { - LIBS *= -llibstdcpp.dll +# STDCPP turns on standard C++ new behaviour (ie. throwing new) +STL_MMP_RULE = "STDCPP" + +# Fall back to old implementation if that is the only one that is found +exists($${EPOCROOT}epoc32/release/armv5/urel/libstdcpp.dll)|exists($${EPOCROOT}epoc32/release/winscw/udeb/libstdcpp.dll) { + !exists($${EPOCROOT}epoc32/release/armv5/urel/libstdcppv5.dll):!exists($${EPOCROOT}epoc32/release/winscw/udeb/libstdcppv5.dll) { + STL_LIB = -llibstdcpp.dll + STL_MMP_RULE = + } } + +LIBS *= $$STL_LIB +MMP_RULES *= $$STL_MMP_RULE -- cgit v0.12 From e9dedf5b10fcc25454d01a588d5000437cb46e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 19 Feb 2010 11:35:17 +0100 Subject: Fixed off-by-one blending errors in the NEON drawhelper code. For example blending alpha 0xff with alpha 0xff and a 0.5 opacity gave a result of 0xfe instead of the correct 0xff. This caused some autotests to fail on ARM/NEON. Reviewed-by: TrustMe --- src/gui/painting/qdrawhelper_neon.cpp | 130 +++++++++++++++++----------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 25860a0..77c5202 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -48,43 +48,43 @@ QT_BEGIN_NAMESPACE -static inline int16x8_t qvdiv_255_s16(int16x8_t x, int16x8_t half) +static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half) { // result = (x + (x >> 8) + 0x80) >> 8 - const int16x8_t temp = vshrq_n_s16(x, 8); // x >> 8 - const int16x8_t sum_part = vaddq_s16(x, half); // x + 0x80 - const int16x8_t sum = vaddq_s16(temp, sum_part); + const uint16x8_t temp = vshrq_n_u16(x, 8); // x >> 8 + const uint16x8_t sum_part = vaddq_u16(x, half); // x + 0x80 + const uint16x8_t sum = vaddq_u16(temp, sum_part); - return vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(sum), 8)); + return vshrq_n_u16(sum, 8); } -static inline int16x8_t qvbyte_mul_s16(int16x8_t x, int16x8_t alpha, int16x8_t half) +static inline uint16x8_t qvbyte_mul_u16(uint16x8_t x, uint16x8_t alpha, uint16x8_t half) { // t = qRound(x * alpha / 255.0) - const int16x8_t t = vmulq_s16(x, alpha); // t - return qvdiv_255_s16(t, half); + const uint16x8_t t = vmulq_u16(x, alpha); // t + return qvdiv_255_u16(t, half); } -static inline int16x8_t qvinterpolate_pixel_255(int16x8_t x, int16x8_t a, int16x8_t y, int16x8_t b, int16x8_t half) +static inline uint16x8_t qvinterpolate_pixel_255(uint16x8_t x, uint16x8_t a, uint16x8_t y, uint16x8_t b, uint16x8_t half) { // t = x * a + y * b - const int16x8_t ta = vmulq_s16(x, a); - const int16x8_t tb = vmulq_s16(y, b); + const uint16x8_t ta = vmulq_u16(x, a); + const uint16x8_t tb = vmulq_u16(y, b); - return qvdiv_255_s16(vaddq_s16(ta, tb), half); + return qvdiv_255_u16(vaddq_u16(ta, tb), half); } -static inline int16x8_t qvsource_over_s16(int16x8_t src16, int16x8_t dst16, int16x8_t half, int16x8_t full) +static inline uint16x8_t qvsource_over_u16(uint16x8_t src16, uint16x8_t dst16, uint16x8_t half, uint16x8_t full) { - const int16x4_t alpha16_high = vdup_lane_s16(vget_high_s16(src16), 3); - const int16x4_t alpha16_low = vdup_lane_s16(vget_low_s16(src16), 3); + const uint16x4_t alpha16_high = vdup_lane_u16(vget_high_u16(src16), 3); + const uint16x4_t alpha16_low = vdup_lane_u16(vget_low_u16(src16), 3); - const int16x8_t alpha16 = vsubq_s16(full, vcombine_s16(alpha16_low, alpha16_high)); + const uint16x8_t alpha16 = vsubq_u16(full, vcombine_u16(alpha16_low, alpha16_high)); - return vaddq_s16(src16, qvbyte_mul_s16(dst16, alpha16, half)); + return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half)); } void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, @@ -94,21 +94,21 @@ void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, { const uint *src = (const uint *) srcPixels; uint *dst = (uint *) destPixels; - int16x8_t half = vdupq_n_s16(0x80); - int16x8_t full = vdupq_n_s16(0xff); + uint16x8_t half = vdupq_n_u16(0x80); + uint16x8_t full = vdupq_n_u16(0xff); if (const_alpha == 256) { for (int y = 0; y < h; ++y) { int x = 0; for (; x < w-3; x += 4) { - int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); + uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) { // all opaque - vst1q_s32((int32_t *)&dst[x], src32); + vst1q_u32((uint32_t *)&dst[x], src32); } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) { - int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - const uint8x16_t src8 = vreinterpretq_u8_s32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + const uint8x16_t src8 = vreinterpretq_u8_u32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); const uint8x8_t src8_low = vget_low_u8(src8); const uint8x8_t dst8_low = vget_low_u8(dst8); @@ -116,19 +116,19 @@ void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, const uint8x8_t src8_high = vget_high_u8(src8); const uint8x8_t dst8_high = vget_high_u8(dst8); - const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); - const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + const uint16x8_t src16_low = vmovl_u8(src8_low); + const uint16x8_t dst16_low = vmovl_u8(dst8_low); - const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); - const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + const uint16x8_t src16_high = vmovl_u8(src8_high); + const uint16x8_t dst16_high = vmovl_u8(dst8_high); - const int16x8_t result16_low = qvsource_over_s16(src16_low, dst16_low, half, full); - const int16x8_t result16_high = qvsource_over_s16(src16_high, dst16_high, half, full); + const uint16x8_t result16_low = qvsource_over_u16(src16_low, dst16_low, half, full); + const uint16x8_t result16_high = qvsource_over_u16(src16_high, dst16_high, half, full); - const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); - const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); + const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); } } for (; x> 8; - int16x8_t const_alpha16 = vdupq_n_s16(const_alpha); + uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha); for (int y = 0; y < h; ++y) { int x = 0; for (; x < w-3; x += 4) { if (src[x] | src[x+1] | src[x+2] | src[x+3]) { - int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); - int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); + uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - const uint8x16_t src8 = vreinterpretq_u8_s32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + const uint8x16_t src8 = vreinterpretq_u8_u32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); const uint8x8_t src8_low = vget_low_u8(src8); const uint8x8_t dst8_low = vget_low_u8(dst8); @@ -160,22 +160,22 @@ void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, const uint8x8_t src8_high = vget_high_u8(src8); const uint8x8_t dst8_high = vget_high_u8(dst8); - const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); - const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + const uint16x8_t src16_low = vmovl_u8(src8_low); + const uint16x8_t dst16_low = vmovl_u8(dst8_low); - const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); - const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + const uint16x8_t src16_high = vmovl_u8(src8_high); + const uint16x8_t dst16_high = vmovl_u8(dst8_high); - const int16x8_t srcalpha16_low = qvbyte_mul_s16(src16_low, const_alpha16, half); - const int16x8_t srcalpha16_high = qvbyte_mul_s16(src16_high, const_alpha16, half); + const uint16x8_t srcalpha16_low = qvbyte_mul_u16(src16_low, const_alpha16, half); + const uint16x8_t srcalpha16_high = qvbyte_mul_u16(src16_high, const_alpha16, half); - const int16x8_t result16_low = qvsource_over_s16(srcalpha16_low, dst16_low, half, full); - const int16x8_t result16_high = qvsource_over_s16(srcalpha16_high, dst16_high, half, full); + const uint16x8_t result16_low = qvsource_over_u16(srcalpha16_low, dst16_low, half, full); + const uint16x8_t result16_high = qvsource_over_u16(srcalpha16_high, dst16_high, half, full); - const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); - const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); + const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); } } for (; x> 8; int one_minus_const_alpha = 255 - const_alpha; - int16x8_t const_alpha16 = vdupq_n_s16(const_alpha); - int16x8_t one_minus_const_alpha16 = vdupq_n_s16(255 - const_alpha); + uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha); + uint16x8_t one_minus_const_alpha16 = vdupq_n_u16(255 - const_alpha); for (int y = 0; y < h; ++y) { int x = 0; for (; x < w-3; x += 4) { - int32x4_t src32 = vld1q_s32((int32_t *)&src[x]); - int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]); + uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); + uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - const uint8x16_t src8 = vreinterpretq_u8_s32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32); + const uint8x16_t src8 = vreinterpretq_u8_u32(src32); + const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); const uint8x8_t src8_low = vget_low_u8(src8); const uint8x8_t dst8_low = vget_low_u8(dst8); @@ -226,19 +226,19 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, const uint8x8_t src8_high = vget_high_u8(src8); const uint8x8_t dst8_high = vget_high_u8(dst8); - const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low)); - const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low)); + const uint16x8_t src16_low = vmovl_u8(src8_low); + const uint16x8_t dst16_low = vmovl_u8(dst8_low); - const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high)); - const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high)); + const uint16x8_t src16_high = vmovl_u8(src8_high); + const uint16x8_t dst16_high = vmovl_u8(dst8_high); - const int16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half); - const int16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half); + const uint16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half); + const uint16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half); - const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low)); - const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high)); + const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); + const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high)); + vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); } for (; x Date: Fri, 19 Feb 2010 13:12:06 +0100 Subject: Ensure that posted events are sent on Windows Commit f21d183 introduced a GetMessage hook that would try to post a message to the Windows queue if the hook received an event that was not the WM_QT_SENDPOSTEDEVENTS message. However, the logic used is flawed, and would never post the message unless we received a message for a window that was not the event dispatcher's internal window. Timer messages DO go to the internal window, and the last handled timer message SHOULD trigger the hook to post a new WM_QT_SENDPOSTEDEVENTS, but due to the flawed logic, it would not. The most notable side effect of this bug is that regular repaints and animations would not become visible unless the user moved the mouse or used the keyboard. Task-number: QTBUG-7728 Reviewed-by: Andreas Aardal Hanssen Fix verified by 2 users in the Jira report mentioned above. --- src/corelib/kernel/qeventdispatcher_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 93becc8..8010a76 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -510,8 +510,8 @@ LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) MSG *msg = (MSG *) lp; if (localSerialNumber != d->lastSerialNumber // if this message IS the one that triggers sendPostedEvents(), no need to post it again - && msg->hwnd != d->internalHwnd - && msg->message != WM_QT_SENDPOSTEDEVENTS) { + && (msg->hwnd != d->internalHwnd + || msg->message != WM_QT_SENDPOSTEDEVENTS)) { PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); } } -- cgit v0.12 From 145f46347bdcdf0efe2821b8ae2c34f53c543d1c Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 19 Feb 2010 14:23:47 +0200 Subject: Supressed Icon sizes on QPushButton in QS60Style QS60Style should have smaller button margins when icon height is larger than text height within a button. Task-number: QTBUG-7586 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 74707af..565cc2c 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2396,10 +2396,20 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_PushButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); - if (const QAbstractButton *buttonWidget = (qobject_cast(widget))) + if (const QAbstractButton *buttonWidget = (qobject_cast(widget))) { if (buttonWidget->isCheckable()) sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); + const int iconHeight = (!buttonWidget->icon().isNull()) ? buttonWidget->iconSize().height() : 0; + const int textHeight = (buttonWidget->text().length() > 0) ? + buttonWidget->fontMetrics().size(Qt::TextSingleLine, buttonWidget->text()).height() : 0; + const int decoratorHeight = (buttonWidget->isCheckable()) ? pixelMetric(PM_IndicatorHeight) : 0; + + const int contentHeight = + qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin), + textHeight + 2*pixelMetric(PM_ButtonMargin)); + sz.setHeight(contentHeight); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0); + } break; case CT_LineEdit: if (const QStyleOptionFrame *f = qstyleoption_cast(opt)) -- cgit v0.12 From 53fce0ced68ae5d828dc19d05caa09e05b4e5151 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 19 Feb 2010 14:47:38 +0100 Subject: Fix building in a namespace on Windows Reviewed-by: hjk --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8235a5c..c08d04a 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -89,6 +89,9 @@ QT_BEGIN_NAMESPACE //#define QT_GL_NO_SCISSOR_TEST +#if defined(Q_WS_WIN) +extern Q_GUI_EXPORT bool qt_cleartype_enabled; +#endif extern QImage qt_imageForBrush(int brushStyle, bool invert); @@ -1555,7 +1558,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) #if !defined(QT_OPENGL_ES_2) #if defined(Q_WS_WIN) - extern Q_GUI_EXPORT bool qt_cleartype_enabled; if (qt_cleartype_enabled) #endif d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; -- cgit v0.12 From 7ce06afb341240b102edcc83b33d0da3d9e7ab5e Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 19 Feb 2010 13:49:58 +0100 Subject: tst_qnetworkreply: Check if TCP/HTTP connection got re-used Reviewed-by: Peter Hartmann --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 131 +++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 049bbb8..78b4d98 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -257,6 +257,11 @@ private Q_SLOTS: void httpConnectionCount(); + void httpReUsingConnectionSequential_data(); + void httpReUsingConnectionSequential(); + void httpReUsingConnectionFromFinishedSlot_data(); + void httpReUsingConnectionFromFinishedSlot(); + void httpRecursiveCreation(); #ifndef QT_NO_OPENSSL @@ -314,18 +319,20 @@ QT_END_NAMESPACE QFAIL(qPrintable(errorMsg)); \ } while (0); + +// Does not work for POST/PUT! class MiniHttpServer: public QTcpServer { Q_OBJECT - QTcpSocket *client; - public: + QTcpSocket *client; // always the last one that was received QByteArray dataToTransmit; QByteArray receivedData; bool doClose; + bool multiple; int totalConnections; - MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true), totalConnections(0) + MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true), multiple(false), totalConnections(0) { listen(); connect(this, SIGNAL(newConnection()), this, SLOT(doAccept())); @@ -335,15 +342,21 @@ public slots: void doAccept() { client = nextPendingConnection(); + client->setParent(this); ++totalConnections; - connect(client, SIGNAL(readyRead()), this, SLOT(sendData())); + connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); } - void sendData() + void readyReadSlot() { receivedData += client->readAll(); - if (receivedData.contains("\r\n\r\n") || - receivedData.contains("\n\n")) { + int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); + + if (doubleEndlPos != -1) { + // multiple requests incoming. remove the bytes of the current one + if (multiple) + receivedData.remove(0, doubleEndlPos+4); + client->write(dataToTransmit); if (doClose) { client->disconnectFromHost(); @@ -3790,6 +3803,110 @@ void tst_QNetworkReply::httpConnectionCount() #endif } +void tst_QNetworkReply::httpReUsingConnectionSequential_data() +{ + QTest::addColumn("doDeleteLater"); + QTest::newRow("deleteLater") << true; + QTest::newRow("noDeleteLater") << false; +} + +void tst_QNetworkReply::httpReUsingConnectionSequential() +{ + QFETCH(bool, doDeleteLater); + + QByteArray response("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + MiniHttpServer server(response); + server.multiple = true; + server.doClose = false; + + QUrl url; + url.setScheme("http"); + url.setPort(server.serverPort()); + url.setHost("127.0.0.1"); + // first request + QNetworkReply* reply1 = manager.get(QNetworkRequest(url)); + connect(reply1, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(!reply1->error()); + int reply1port = server.client->peerPort(); + + if (doDeleteLater) + reply1->deleteLater(); + + // finished received, send the next one + QNetworkReply*reply2 = manager.get(QNetworkRequest(url)); + connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(!reply2->error()); + int reply2port = server.client->peerPort(); // should still be the same object + + QVERIFY(reply1port > 0); + QCOMPARE(server.totalConnections, 1); + QCOMPARE(reply2port, reply1port); + + if (!doDeleteLater) + reply1->deleteLater(); // only do it if it was not done earlier + reply2->deleteLater(); +} + +class HttpReUsingConnectionFromFinishedSlot : public QObject { + Q_OBJECT; +public: + QNetworkReply* reply1; + QNetworkReply* reply2; + QUrl url; + QNetworkAccessManager manager; +public slots: + void finishedSlot() { + QVERIFY(!reply1->error()); + + QFETCH(bool, doDeleteLater); + if (doDeleteLater) { + reply1->deleteLater(); + reply1 = 0; + } + + // kick off 2nd request and exit the loop when it is done + reply2 = manager.get(QNetworkRequest(url)); + reply2->setParent(this); + connect(reply2, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + } +}; + +void tst_QNetworkReply::httpReUsingConnectionFromFinishedSlot_data() +{ + httpReUsingConnectionSequential_data(); +} + +void tst_QNetworkReply::httpReUsingConnectionFromFinishedSlot() +{ + QByteArray response("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + MiniHttpServer server(response); + server.multiple = true; + server.doClose = false; + + HttpReUsingConnectionFromFinishedSlot helper; + helper.reply1 = 0; + helper.reply2 = 0; + helper.url.setScheme("http"); + helper.url.setPort(server.serverPort()); + helper.url.setHost("127.0.0.1"); + + // first request + helper.reply1 = helper.manager.get(QNetworkRequest(helper.url)); + helper.reply1->setParent(&helper); + connect(helper.reply1, SIGNAL(finished()), &helper, SLOT(finishedSlot())); + QTestEventLoop::instance().enterLoop(4); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(helper.reply2); + QVERIFY(!helper.reply2->error()); + + QCOMPARE(server.totalConnections, 1); +} + class HttpRecursiveCreationHelper : public QObject { Q_OBJECT public: -- cgit v0.12 From 4cabe964bc02e07fe96dd8fda5f8c73a6e1d6a12 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 19 Feb 2010 14:32:17 +0000 Subject: Fix incorrect license headers Fixes incorrect license headers used on files added by 28610950. --- src/plugins/audio/symbian/main.cpp | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudio.h | 36 +++++++++++----------- .../audio/symbian/symbianaudiodeviceinfo.cpp | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudiodeviceinfo.h | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudioinput.cpp | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudioinput.h | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudiooutput.cpp | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudiooutput.h | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudioutils.cpp | 36 +++++++++++----------- src/plugins/audio/symbian/symbianaudioutils.h | 36 +++++++++++----------- 10 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/plugins/audio/symbian/main.cpp b/src/plugins/audio/symbian/main.cpp index 377944b..2299f8e 100644 --- a/src/plugins/audio/symbian/main.cpp +++ b/src/plugins/audio/symbian/main.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudio.h b/src/plugins/audio/symbian/symbianaudio.h index 527aa55..cfd08f1 100644 --- a/src/plugins/audio/symbian/symbianaudio.h +++ b/src/plugins/audio/symbian/symbianaudio.h @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp index b8d59de..1e57a06 100644 --- a/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.h b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h index 1df6afb..7916ddb 100644 --- a/src/plugins/audio/symbian/symbianaudiodeviceinfo.h +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudioinput.cpp b/src/plugins/audio/symbian/symbianaudioinput.cpp index c1a6299..e442c11 100644 --- a/src/plugins/audio/symbian/symbianaudioinput.cpp +++ b/src/plugins/audio/symbian/symbianaudioinput.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudioinput.h b/src/plugins/audio/symbian/symbianaudioinput.h index 0497d7a..3f27ec5 100644 --- a/src/plugins/audio/symbian/symbianaudioinput.h +++ b/src/plugins/audio/symbian/symbianaudioinput.h @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudiooutput.cpp b/src/plugins/audio/symbian/symbianaudiooutput.cpp index 7e05211..501a262 100644 --- a/src/plugins/audio/symbian/symbianaudiooutput.cpp +++ b/src/plugins/audio/symbian/symbianaudiooutput.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudiooutput.h b/src/plugins/audio/symbian/symbianaudiooutput.h index 4db97c3..5bfcf44 100644 --- a/src/plugins/audio/symbian/symbianaudiooutput.h +++ b/src/plugins/audio/symbian/symbianaudiooutput.h @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudioutils.cpp b/src/plugins/audio/symbian/symbianaudioutils.cpp index 13ea03d..64288f9 100644 --- a/src/plugins/audio/symbian/symbianaudioutils.cpp +++ b/src/plugins/audio/symbian/symbianaudioutils.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/plugins/audio/symbian/symbianaudioutils.h b/src/plugins/audio/symbian/symbianaudioutils.h index d9f992a..4aa891e 100644 --- a/src/plugins/audio/symbian/symbianaudioutils.h +++ b/src/plugins/audio/symbian/symbianaudioutils.h @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the FOO module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From fb5a1ad19109fe0eb88a84dd5e4b86c9849b90e6 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 19 Feb 2010 14:39:48 +0000 Subject: Fix incorrect license headers Forgot to fill in the module name in 4cabe964. --- src/plugins/audio/symbian/main.cpp | 2 +- src/plugins/audio/symbian/symbianaudio.h | 2 +- src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp | 2 +- src/plugins/audio/symbian/symbianaudiodeviceinfo.h | 2 +- src/plugins/audio/symbian/symbianaudioinput.cpp | 2 +- src/plugins/audio/symbian/symbianaudioinput.h | 2 +- src/plugins/audio/symbian/symbianaudiooutput.cpp | 2 +- src/plugins/audio/symbian/symbianaudiooutput.h | 2 +- src/plugins/audio/symbian/symbianaudioutils.cpp | 2 +- src/plugins/audio/symbian/symbianaudioutils.h | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/plugins/audio/symbian/main.cpp b/src/plugins/audio/symbian/main.cpp index 2299f8e..536a8ec 100644 --- a/src/plugins/audio/symbian/main.cpp +++ b/src/plugins/audio/symbian/main.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudio.h b/src/plugins/audio/symbian/symbianaudio.h index cfd08f1..3fc0419 100644 --- a/src/plugins/audio/symbian/symbianaudio.h +++ b/src/plugins/audio/symbian/symbianaudio.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp index 1e57a06..9701dad 100644 --- a/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudiodeviceinfo.h b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h index 7916ddb..250804d 100644 --- a/src/plugins/audio/symbian/symbianaudiodeviceinfo.h +++ b/src/plugins/audio/symbian/symbianaudiodeviceinfo.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudioinput.cpp b/src/plugins/audio/symbian/symbianaudioinput.cpp index e442c11..8200925 100644 --- a/src/plugins/audio/symbian/symbianaudioinput.cpp +++ b/src/plugins/audio/symbian/symbianaudioinput.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudioinput.h b/src/plugins/audio/symbian/symbianaudioinput.h index 3f27ec5..34b7d38 100644 --- a/src/plugins/audio/symbian/symbianaudioinput.h +++ b/src/plugins/audio/symbian/symbianaudioinput.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudiooutput.cpp b/src/plugins/audio/symbian/symbianaudiooutput.cpp index 501a262..385e169 100644 --- a/src/plugins/audio/symbian/symbianaudiooutput.cpp +++ b/src/plugins/audio/symbian/symbianaudiooutput.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudiooutput.h b/src/plugins/audio/symbian/symbianaudiooutput.h index 5bfcf44..8994e46 100644 --- a/src/plugins/audio/symbian/symbianaudiooutput.h +++ b/src/plugins/audio/symbian/symbianaudiooutput.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudioutils.cpp b/src/plugins/audio/symbian/symbianaudioutils.cpp index 64288f9..f04c198 100644 --- a/src/plugins/audio/symbian/symbianaudioutils.cpp +++ b/src/plugins/audio/symbian/symbianaudioutils.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/src/plugins/audio/symbian/symbianaudioutils.h b/src/plugins/audio/symbian/symbianaudioutils.h index 4aa891e..53274e0 100644 --- a/src/plugins/audio/symbian/symbianaudioutils.h +++ b/src/plugins/audio/symbian/symbianaudioutils.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage -- cgit v0.12 From 0a7816943b11bb0338ee2cf880382825185058b4 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 Feb 2010 15:07:31 +0100 Subject: Get rid of the dependency on the Symbian app layer miutset.h is coming from the app layer that we are not supposed to use. Since we still need the constant we're better off working around the dependency and to forward declare the one constant we need from the file. Reviewed-By: Iain --- src/gui/util/qdesktopservices_s60.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp index 319c4b0..adc4fc1 100644 --- a/src/gui/util/qdesktopservices_s60.cpp +++ b/src/gui/util/qdesktopservices_s60.cpp @@ -48,7 +48,6 @@ #include #include -#include // KUidMsgTypeSMTP #include // CRichText #include // TDriveUnit etc #include // CEikonEnv @@ -57,6 +56,9 @@ #include // RSendAs #include // RSendAsMessage +// copied from miutset.h, so we don't get a dependency into the app layer +const TUid KUidMsgTypeSMTP = {0x10001028}; // 268439592 + #ifdef Q_WS_S60 # include // PathInfo # ifdef USE_DOCUMENTHANDLER -- cgit v0.12 From 54ac311352fd69e05481b739ddd2c937f4e7b858 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 Feb 2010 15:55:45 +0100 Subject: work around the current include file structure on Symbian^3 Reviewed-By: Iain --- src/qbase.pri | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qbase.pri b/src/qbase.pri index db55365..6f2dfa4 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -108,6 +108,10 @@ symbian { } } load(armcc_warnings) + + # workaround for the fact that some of our required includes in Symbian^3 + # now depend upon files in epoc32/include/platform + INCLUDEPATH += $$OS_LAYER_SYSTEMINCLUDE } win32-borland:INCLUDEPATH += kernel -- cgit v0.12 From ee395a5b2f9e0d5f26884dbf40d06f3df7671282 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 Feb 2010 15:12:28 +0100 Subject: use egl properties when creating surfaces on symbian We are currently getting non premultiplied surfaces on symbian since we do not forward the egl properties that we'd like to have to the driver. Reviewed-By: Jason Barron --- src/gui/egl/qegl_symbian.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index b1c9408..5a010cd 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -78,9 +78,9 @@ EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties props = 0; EGLSurface surf; if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, 0); + surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props); else - surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, 0); + surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); return surf; -- cgit v0.12