diff -r 11d3954df52a -r 627c4a0fd0e7 src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp --- a/src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp Thu May 27 13:10:59 2010 +0300 +++ b/src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp Fri Jun 11 13:58:22 2010 +0300 @@ -62,12 +62,16 @@ const char *last_output_dir_key = "lastoutdir"; HbSplashGenerator::HbSplashGenerator() - : mBusy(false), mForceRegen(false), mMainWindow(0), mFirstRegenerate(true) + : mMainWindowLocked(false), + mProcessQueuePending(false), + mForceRegen(false), + mMainWindow(0), + mFirstRegenerate(true) { #if defined(Q_OS_SYMBIAN) CCoeEnv::Static()->FsSession().CreatePrivatePath(EDriveC); QString iniFileName = QString("c:/private/%1/hbsplashgen.ini") - .arg(QString::number(hbsplash_server_uid3.iUid, 16)); + .arg(QString::number(hbsplash_server_uid3.iUid, 16)); mSettings = new QSettings(iniFileName, QSettings::IniFormat, this); #else mSettings = new QSettings("Nokia", "HbSplash", this); @@ -131,7 +135,7 @@ // Watch also the directories containing splashml files. Files may // be added/updated at any time. connect(&mFsWatcher, SIGNAL(directoryChanged(QString)), SLOT(onDirectoryChanged(QString))); - foreach (const QString &dir, hbsplash_splashml_dirs()) { + foreach(const QString & dir, hbsplash_splashml_dirs()) { // Check for directory existence before calling addPath() to // avoid printing warnings. if (QDir(dir).exists()) { @@ -154,11 +158,10 @@ qDebug() << PRE << "last regen:" << lastTheme << lastLang << lastFileCount << lastOutputDir << "current:" << currentTheme << currentLang << currentFileCount << currentOutputDir; if (mForceRegen - || currentTheme != lastTheme - || currentLang != lastLang - || currentFileCount != lastFileCount - || currentOutputDir != lastOutputDir) - { + || currentTheme != lastTheme + || currentLang != lastLang + || currentFileCount != lastFileCount + || currentOutputDir != lastOutputDir) { QMetaObject::invokeMethod(this, "regenerate", Qt::QueuedConnection); } } @@ -188,7 +191,7 @@ QDir outDir(hbsplash_output_dir()); if (outDir.exists()) { QStringList names = outDir.entryList(QStringList() << "*", QDir::Files); - foreach (const QString &name, names) { + foreach(const QString & name, names) { outDir.remove(name); } } @@ -273,13 +276,15 @@ qDebug() << PRE << "processQueue() over"; return; } - // If a previous splash generation is still in progress then do nothing. - if (mBusy) { + // If a previous splash generation is still in progress or a compositor is + // working then do nothing. + if (!lockMainWindow()) { + mProcessQueuePending = true; qDebug() << PRE << "still busy processQueue() over"; return; } try { - mBusy = true; + mProcessQueuePending = false; mItem = mQueue.dequeue(); mItemTime.start(); log("generating splash screen", mItem.mThemeName, mItem.mOrientation); @@ -302,7 +307,7 @@ qDebug() << PRE << "processQueue() over"; } -void HbSplashGenerator::ensureMainWindow() +HbMainWindow *HbSplashGenerator::ensureMainWindow() { if (!mMainWindow) { // The FixedVertical flag is used just to disable the sensor-based @@ -312,6 +317,7 @@ // construction is done right now. HbMainWindowPrivate::d_ptr(mMainWindow)->_q_delayedConstruction(); } + return mMainWindow; } void HbSplashGenerator::processWindow() @@ -322,13 +328,13 @@ qDebug() << PRE << "total time for screen (ms):" << mItemTime.elapsed(); QList views = mMainWindow->views(); - foreach (HbView *view, views) { + foreach(HbView * view, views) { mMainWindow->removeView(view); delete view; } clearTranslators(); - mBusy = false; + unlockMainWindowInternal(); QMetaObject::invokeMethod(this, "processQueue", Qt::QueuedConnection); log("processWindow() over", mItem.mThemeName, mItem.mOrientation); } @@ -386,12 +392,6 @@ return splashFile; } -// helper to avoid calling the non-const version of QImage::bits() -inline const uchar *imageBits(const QImage &image) -{ - return image.bits(); -} - bool HbSplashGenerator::saveSpl(const QString &nameWithoutExt, const QImage &image, quint32 extra) { QString fn(nameWithoutExt); @@ -407,7 +407,7 @@ f.write((char *) &bpl, sizeof(quint32)); f.write((char *) &fmt, sizeof(qint32)); f.write((char *) &extra, sizeof(quint32)); - f.write((const char *) imageBits(image), bpl * h); + f.write((const char *) image.bits(), bpl * h); f.close(); return true; } @@ -420,10 +420,11 @@ delete mMainWindow; mMainWindow = 0; clearTranslators(); - mBusy = false; + unlockMainWindowInternal(); + mProcessQueuePending = false; } -QDebug operator<<(QDebug dbg, const HbSplashGenerator::QueueItem& item) +QDebug operator<<(QDebug dbg, const HbSplashGenerator::QueueItem &item) { dbg << "[" << item.mDocmlFileName @@ -469,13 +470,13 @@ { QSet processedFileNames; QStringList dirNames(hbsplash_splashml_dirs()); - foreach (const QString &dirName, dirNames) { + foreach(const QString & dirName, dirNames) { QDir dir(dirName); if (!dir.exists()) { continue; } QStringList entries = dir.entryList(QStringList() << "*.splashml", QDir::Files); - foreach (const QString &entry, entries) { + foreach(const QString & entry, entries) { // Skip if a file with the same name has already been processed from // a different location. if (processedFileNames.contains(entry)) { @@ -496,10 +497,9 @@ QueueItem item(themeName, orientation); bool ok = parseSplashml(fullName, item); if (ok - && !item.mAppId.isEmpty() - && !item.mDocmlWidgetName.isEmpty() - && !item.mDocmlFileName.isEmpty()) - { + && !item.mAppId.isEmpty() + && !item.mDocmlWidgetName.isEmpty() + && !item.mDocmlFileName.isEmpty()) { // Add the full path to the filename. The docml is supposed to // be in the same directory as the splashml. item.mDocmlFileName = dir.filePath(item.mDocmlFileName); @@ -533,8 +533,7 @@ ok = false; break; } else if (token == QXmlStreamReader::StartElement - && xml.name() == QLatin1String("hbsplash")) - { + && xml.name() == QLatin1String("hbsplash")) { docOk = true; } else if (docOk) { parseSplashmlElements(xml, item, fullFileName); @@ -552,8 +551,8 @@ } void HbSplashGenerator::parseSplashmlElements(QXmlStreamReader &xml, - QueueItem &item, - const QString &fullFileName) + QueueItem &item, + const QString &fullFileName) { if (xml.isStartElement()) { QStringRef name = xml.name(); @@ -563,7 +562,7 @@ item.mDocmlWidgetName = xml.readElementText().trimmed(); } else if (name == QLatin1String("appid") || name == QLatin1String("appuid")) { item.mAppId = xml.readElementText().trimmed(); - if (item.mAppId.startsWith("0x")) { + if (item.mAppId.startsWith(QLatin1String("0x"))) { item.mAppId.remove(0, 2); } } else if (name == QLatin1String("screenid")) { @@ -571,7 +570,7 @@ } else if (name == QLatin1String("tsappname")) { item.mTsAppName = xml.readElementText().trimmed(); } else if (name == QLatin1String("view-flags")) { - item.mViewFlags = xml.readElementText().split(",", QString::SkipEmptyParts); + item.mViewFlags = xml.readElementText().split(',', QString::SkipEmptyParts); for (int i = 0, ie = item.mViewFlags.count(); i != ie; ++i) { item.mViewFlags[i] = item.mViewFlags[i].trimmed().toLower(); } @@ -617,7 +616,7 @@ req.mFrameGraphicsType = HbFrameDrawer::ThreePiecesVertical; } else if (type == QLatin1String("9")) { req.mFrameGraphicsType = HbFrameDrawer::NinePieces; - } + } QString z = xml.attributes().value("z").toString().trimmed(); if (z.isEmpty()) { req.mZValue = -1; @@ -690,10 +689,12 @@ CustomDocumentLoader loader(mMainWindow, mItem); QStringList sections; if (!mItem.mCondSections.isEmpty()) { - if (mItem.mCondSections.contains("portrait") && mItem.mOrientation == Qt::Vertical) { - sections << mItem.mCondSections.value("portrait"); - } else if (mItem.mCondSections.contains("landscape") && mItem.mOrientation == Qt::Horizontal) { - sections << mItem.mCondSections.value("landscape"); + QLatin1String prtKey("portrait"); + QLatin1String lscKey("landscape"); + if (mItem.mCondSections.contains(prtKey) && mItem.mOrientation == Qt::Vertical) { + sections << mItem.mCondSections.value(prtKey); + } else if (mItem.mCondSections.contains(lscKey) && mItem.mOrientation == Qt::Horizontal) { + sections << mItem.mCondSections.value(lscKey); } } sections << mItem.mForcedSections; @@ -701,7 +702,7 @@ bool ok; loader.load(mItem.mDocmlFileName, &ok); if (ok && !sections.isEmpty()) { - foreach (const QString §ion, sections) { + foreach(const QString & section, sections) { qDebug() << PRE << "loading" << mItem.mDocmlFileName << "section" << section; loader.load(mItem.mDocmlFileName, section, &ok); } @@ -728,8 +729,7 @@ for (int i = 0, ie = mItem.mItemBgGraphics.count(); i != ie; ++i) { QueueItem::ItemBgGraphicsRequest req = mItem.mItemBgGraphics.at(i); if ((req.mOrientation == QLatin1String("portrait") && mItem.mOrientation != Qt::Vertical) - || (req.mOrientation == QLatin1String("landscape") && mItem.mOrientation != Qt::Horizontal)) - { + || (req.mOrientation == QLatin1String("landscape") && mItem.mOrientation != Qt::Horizontal)) { continue; } HbWidget *widget = qobject_cast(loader.findWidget(req.mTargetWidgetName)); @@ -756,35 +756,34 @@ // view-flags HbView::HbViewFlags viewFlags = view->viewFlags(); - if (mItem.mViewFlags.contains("tb-minimizable")) { + if (mItem.mViewFlags.contains(QLatin1String("tb-minimizable"))) { viewFlags |= HbView::ViewTitleBarMinimizable; } - if (mItem.mViewFlags.contains("tb-minimized")) { + if (mItem.mViewFlags.contains(QLatin1String("tb-minimized"))) { viewFlags |= HbView::ViewTitleBarMinimized; } - if (mItem.mViewFlags.contains("tb-hidden")) { + if (mItem.mViewFlags.contains(QLatin1String("tb-hidden"))) { viewFlags |= HbView::ViewTitleBarHidden; } - if (mItem.mViewFlags.contains("tb-transparent")) { + if (mItem.mViewFlags.contains(QLatin1String("tb-transparent"))) { viewFlags |= HbView::ViewTitleBarTransparent; } - if (mItem.mViewFlags.contains("tb-floating")) { + if (mItem.mViewFlags.contains(QLatin1String("tb-floating"))) { viewFlags |= HbView::ViewTitleBarFloating; } - if (mItem.mViewFlags.contains("sb-hidden")) { + if (mItem.mViewFlags.contains(QLatin1String("sb-hidden"))) { viewFlags |= HbView::ViewStatusBarHidden; } - if (mItem.mViewFlags.contains("sb-transparent")) { + if (mItem.mViewFlags.contains(QLatin1String("sb-transparent"))) { viewFlags |= HbView::ViewStatusBarTransparent; } - if (mItem.mViewFlags.contains("sb-floating")) { + if (mItem.mViewFlags.contains(QLatin1String("sb-floating"))) { viewFlags |= HbView::ViewStatusBarFloating; } view->setViewFlags(viewFlags); if (viewFlags.testFlag(HbView::ViewStatusBarHidden) - || viewFlags.testFlag(HbView::ViewStatusBarTransparent)) - { - mItem.mFlagsToStore |= 1; + || viewFlags.testFlag(HbView::ViewStatusBarTransparent)) { + mItem.mFlagsToStore |= HbSplashNonStandardStatusBar; } // navi-action-icon @@ -812,7 +811,7 @@ HbBackgroundItem *bgItem = mwd->mBgItem; if (bgItem) { QString backgroundImageName = mItem.mBackgroundImageName.value( - mItem.mOrientation == Qt::Vertical ? "portrait" : "landscape"); + mItem.mOrientation == Qt::Vertical ? "portrait" : "landscape"); if (backgroundImageName.isEmpty()) { backgroundImageName = mItem.mBackgroundImageName.value("always"); if (backgroundImageName.isEmpty()) { @@ -824,15 +823,15 @@ } // Hide dynamic content from status bar (clock, indicators). - setStatusBarElementsVisible(false); + setStatusBarElementsVisible(mMainWindow, false); } -void HbSplashGenerator::setStatusBarElementsVisible(bool visible) +void HbSplashGenerator::setStatusBarElementsVisible(HbMainWindow *mw, bool visible) { - HbMainWindowPrivate *mwd = HbMainWindowPrivate::d_ptr(mMainWindow); + HbMainWindowPrivate *mwd = HbMainWindowPrivate::d_ptr(mw); HbStatusBar *statusBar = mwd->mStatusBar; if (statusBar) { - foreach (QGraphicsItem *item, statusBar->childItems()) { + foreach(QGraphicsItem * item, statusBar->childItems()) { QString name = HbStyle::itemName(item); bool knownItem = name == QLatin1String("signal") @@ -854,7 +853,7 @@ bool ok = false; QStringList dirNames(hbsplash_translation_dirs()); dirNames.append(mItem.mCustomTrDirs); - foreach (const QString &dirName, dirNames) { + foreach(const QString & dirName, dirNames) { QDir dir(dirName); QString fullName = dir.filePath(name + '_' + lang); // fullName is not necessarily an existing file, however the translator @@ -876,7 +875,7 @@ void HbSplashGenerator::clearTranslators() { - foreach (QTranslator *translator, mTranslators) { + foreach(QTranslator * translator, mTranslators) { QCoreApplication::removeTranslator(translator); } qDeleteAll(mTranslators); @@ -891,3 +890,27 @@ // directory-changed notifications. QTimer::singleShot(1000, this, SLOT(regenerate())); } + +bool HbSplashGenerator::lockMainWindow() +{ + if (!mMainWindowLocked) { + mMainWindowLocked = true; + return true; + } + return false; +} + +void HbSplashGenerator::unlockMainWindowInternal() +{ + mMainWindowLocked = false; +} + +void HbSplashGenerator::unlockMainWindow() +{ + // This version is used by the compositors. Besides resetting the flag it + // also queues a call to processQueue() if needed. + unlockMainWindowInternal(); + if (mProcessQueuePending) { + QMetaObject::invokeMethod(this, "processQueue", Qt::QueuedConnection); + } +}