src/hbservers/hbsplashgenerator/hbsplashgenerator.cpp
changeset 5 627c4a0fd0e7
parent 3 11d3954df52a
child 7 923ff622b8b9
--- 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<HbView *> 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<QString> 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 &section, 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<HbWidget *>(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);
+    }
+}