src/hbservers/hbsplashgenerator/hbsplashindicompositor.cpp
changeset 5 627c4a0fd0e7
child 7 923ff622b8b9
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbServers module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbsplashindicompositor_p.h"
       
    27 #include "hbsplashgenerator_p.h"
       
    28 #include "hbsplashdefs_p.h"
       
    29 #include "hbmainwindow.h"
       
    30 #include "hbmainwindow_p.h"
       
    31 #include "hbstatusbar_p.h"
       
    32 #include "hbsleepmodelistener_p.h"
       
    33 #include "hbevent.h"
       
    34 #include <QTimer>
       
    35 #include <QApplication>
       
    36 #include <QDebug>
       
    37 
       
    38 #ifdef Q_OS_SYMBIAN
       
    39 #include <fbs.h>
       
    40 #endif
       
    41 
       
    42 // The indicator compositor renders a part of the mainwindow (the
       
    43 // statusbar) into an image from time to time. This pixel data is then
       
    44 // copied over to the splash screen bitmap whenever a client requests
       
    45 // a screen (except if the screen is marked having a non-standard
       
    46 // (hidden or transparent) statusbar).
       
    47 //
       
    48 // This ensures that there will be relatively up-to-date indicators in
       
    49 // the splash screens.
       
    50 
       
    51 #define PRE "[hbsplashgenerator] [indicompositor]"
       
    52 
       
    53 HbSplashIndicatorCompositor::HbSplashIndicatorCompositor(HbSplashGenerator *gen)
       
    54     : mGenerator(gen)
       
    55 {
       
    56 #ifdef HB_SPLASH_STATUSBAR_ENABLED
       
    57     // When the splash screens are regenerated the statusbar must be rendered
       
    58     // again too because the theme or the splashml files may have changed.
       
    59     connect(mGenerator, SIGNAL(finished()), SLOT(renderStatusBar()), Qt::QueuedConnection);
       
    60 
       
    61     // Regenerate every minute to have an up-to-date clock.
       
    62     // ### replace with notifications from indicator fw
       
    63     mRenderTimer = new QTimer(this);
       
    64     connect(mRenderTimer, SIGNAL(timeout()), SLOT(renderStatusBar()));
       
    65     mRenderTimer->setInterval(60000); // 1 min
       
    66     mRenderTimer->start();
       
    67 
       
    68     // There must be no activity while the device is sleeping so listen to sleep
       
    69     // mode events too.
       
    70     HbSleepModeListener::instance(); // just to make sure it is created
       
    71     QApplication::instance()->installEventFilter(this);
       
    72 #endif
       
    73 }
       
    74 
       
    75 void HbSplashIndicatorCompositor::release()
       
    76 {
       
    77     delete this;
       
    78 }
       
    79 
       
    80 void HbSplashIndicatorCompositor::renderStatusBar()
       
    81 {
       
    82     // Try again later if a screen is just being generated. We share the same
       
    83     // mainwindow and our changes done here (orientation, statusbar visibility)
       
    84     // could possibly ruin the output.
       
    85     if (!mGenerator->lockMainWindow()) {
       
    86         QTimer::singleShot(1000, this, SLOT(renderStatusBar()));
       
    87         return;
       
    88     }
       
    89     try {
       
    90         HbMainWindow *mw = mGenerator->ensureMainWindow();
       
    91         HbSplashGenerator::setStatusBarElementsVisible(mw, true);
       
    92         mw->setOrientation(Qt::Vertical, false);
       
    93         doRender(mw, &mStatusBarImagePrt, &mStatusBarRectPrt);
       
    94         mw->setOrientation(Qt::Horizontal, false);
       
    95         doRender(mw, &mStatusBarImageLsc, &mStatusBarRectLsc);
       
    96     } catch (const std::bad_alloc &) {
       
    97         mStatusBarImagePrt = mStatusBarImageLsc = QImage();
       
    98     }
       
    99     mGenerator->unlockMainWindow();
       
   100 }
       
   101 
       
   102 void HbSplashIndicatorCompositor::doRender(HbMainWindow *mw,
       
   103         QImage *statusBarImage,
       
   104         QRect *statusBarRect)
       
   105 {
       
   106     *statusBarRect = mw->mapFromScene(HbMainWindowPrivate::d_ptr(mw)->mStatusBar->geometry())
       
   107                      .boundingRect().intersected(QRect(QPoint(0, 0), mw->size()));
       
   108     qDebug() << PRE << "rendering status bar" << *statusBarRect;
       
   109     *statusBarImage = QImage(statusBarRect->size(), QImage::Format_ARGB32_Premultiplied);
       
   110     statusBarImage->fill(QColor(Qt::transparent).rgba());
       
   111     QPainter painter(statusBarImage);
       
   112     mw->render(&painter, statusBarImage->rect(), *statusBarRect);
       
   113 }
       
   114 
       
   115 void HbSplashIndicatorCompositor::composeToBitmap(void *bitmap,
       
   116         Qt::Orientation orientation,
       
   117         int splashExtraFlags)
       
   118 {
       
   119 #ifdef Q_OS_SYMBIAN
       
   120     if (!(splashExtraFlags & HbSplashNonStandardStatusBar)) {
       
   121         const QImage *srcImg = orientation == Qt::Horizontal ? &mStatusBarImageLsc
       
   122                                : &mStatusBarImagePrt;
       
   123         const QRect *sbRect = orientation == Qt::Horizontal ? &mStatusBarRectLsc
       
   124                               : &mStatusBarRectPrt;
       
   125         if (!srcImg->isNull()) {
       
   126             qDebug() << PRE << "composeToBitmap" << bitmap << orientation << splashExtraFlags;
       
   127             CFbsBitmap *bmp = static_cast<CFbsBitmap *>(bitmap);
       
   128             uchar *dst = reinterpret_cast<uchar *>(bmp->DataAddress());
       
   129             const int dstBpl = CFbsBitmap::ScanLineLength(bmp->SizeInPixels().iWidth,
       
   130                                bmp->DisplayMode());
       
   131             const uchar *src = srcImg->bits();
       
   132             const int srcBpl = srcImg->bytesPerLine();
       
   133             const int dstLineStartOffset = sbRect->left() * 4;
       
   134             const int y0 = sbRect->top();
       
   135             const int y1 = sbRect->bottom();
       
   136             for (int y = y0; y <= y1; ++y) {
       
   137                 int dstOffset = y * dstBpl + dstLineStartOffset;
       
   138                 int srcOffset = (y - y0) * srcBpl;
       
   139                 qMemCopy(dst + dstOffset, src + srcOffset, srcBpl);
       
   140             }
       
   141         }
       
   142     }
       
   143 #else
       
   144     Q_UNUSED(bitmap);
       
   145     Q_UNUSED(orientation);
       
   146     Q_UNUSED(splashExtraFlags);
       
   147 #endif
       
   148 }
       
   149 
       
   150 bool HbSplashIndicatorCompositor::eventFilter(QObject *obj, QEvent *event)
       
   151 {
       
   152     if (event->type() == HbEvent::SleepModeEnter && mRenderTimer->isActive()) {
       
   153         qDebug() << PRE << "entering sleep mode";
       
   154         mRenderTimer->stop();
       
   155     } else if (event->type() == HbEvent::SleepModeExit && !mRenderTimer->isActive()) {
       
   156         qDebug() << PRE << "leaving sleep mode";
       
   157         mRenderTimer->start();
       
   158     }
       
   159     return QObject::eventFilter(obj, event);
       
   160 }