src/hbcore/gui/hbglobalstatusbar.cpp
changeset 30 80e4d18b72f5
equal deleted inserted replaced
28:b7da29130b0e 30:80e4d18b72f5
       
     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 HbCore 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 "hbglobalstatusbar_r.h"
       
    27 #include "hbsplashdefs_p.h"
       
    28 #include <QScopedPointer>
       
    29 
       
    30 /*!
       
    31   \class HbGlobalStatusBar
       
    32 
       
    33   \brief Provides access and change notifications for the image (screenshot) of
       
    34   the statusbar rendered in background by the hbsplashgenerator process.
       
    35 
       
    36   \internal
       
    37 */
       
    38 
       
    39 #ifdef Q_OS_SYMBIAN
       
    40 #include <e32base.h>
       
    41 #include <fbs.h>
       
    42 #include <e32property.h>
       
    43 
       
    44 class BitmapHandleWatcher : public CActive
       
    45 {
       
    46 public:
       
    47     BitmapHandleWatcher(HbSplashStatusBarKeys key, TCallBack callback);
       
    48     ~BitmapHandleWatcher();
       
    49     void DoCancel();
       
    50     void RunL();
       
    51     TInt value();
       
    52 
       
    53 private:
       
    54     RProperty mProperty;
       
    55     TCallBack mCallback;
       
    56 };
       
    57 
       
    58 BitmapHandleWatcher::BitmapHandleWatcher(HbSplashStatusBarKeys key, TCallBack callback)
       
    59     : CActive(EPriorityStandard)
       
    60 {
       
    61     CActiveScheduler::Add(this);
       
    62     if (mProperty.Attach(hbsplash_server_uid3, key) == KErrNone) {
       
    63         mCallback = callback;
       
    64         mProperty.Subscribe(iStatus);
       
    65         SetActive();
       
    66     }
       
    67 }
       
    68 
       
    69 BitmapHandleWatcher::~BitmapHandleWatcher()
       
    70 {
       
    71     Cancel();
       
    72     mProperty.Close();
       
    73 }
       
    74 
       
    75 void BitmapHandleWatcher::DoCancel()
       
    76 {
       
    77     mProperty.Cancel();
       
    78 }
       
    79 
       
    80 void BitmapHandleWatcher::RunL()
       
    81 {
       
    82     if (iStatus != KErrCancel) {
       
    83         mProperty.Subscribe(iStatus);
       
    84         SetActive();
       
    85         if (mCallback.iFunction) {
       
    86             mCallback.CallBack();
       
    87         }
       
    88     }
       
    89 }
       
    90 
       
    91 TInt BitmapHandleWatcher::value()
       
    92 {
       
    93     TInt v = 0;
       
    94     mProperty.Get(v);
       
    95     return v;
       
    96 }
       
    97 
       
    98 class HbGlobalStatusBarPrivate
       
    99 {
       
   100 public:
       
   101     HbGlobalStatusBarPrivate(HbGlobalStatusBar *q);
       
   102     ~HbGlobalStatusBarPrivate();
       
   103     static TInt splashImageChanged(TAny *param);
       
   104     TInt bitmapHandle(Qt::Orientation orientation);
       
   105     CFbsBitmap **storedBitmap(Qt::Orientation orientation);
       
   106 
       
   107     CFbsBitmap *mBmpPrt;
       
   108     CFbsBitmap *mBmpLsc;
       
   109     QScopedPointer<BitmapHandleWatcher> mPrt;
       
   110     QScopedPointer<BitmapHandleWatcher> mLsc;
       
   111 };
       
   112 
       
   113 HbGlobalStatusBarPrivate::HbGlobalStatusBarPrivate(HbGlobalStatusBar *q)
       
   114     : mBmpPrt(0), mBmpLsc(0)
       
   115 {
       
   116     // Don't emit changed() twice, it's enough to have one callback because both
       
   117     // statusbars are regenerated for every change. Note however that passing
       
   118     // TCallBack() would cause a compiler warning with armcc because iPtr is
       
   119     // left uninitialized, so specify 0 explicitly.
       
   120     mPrt.reset(new BitmapHandleWatcher(HbSplashSbBitmapPrtKey, TCallBack(0, 0)));
       
   121     mLsc.reset(new BitmapHandleWatcher(HbSplashSbBitmapLscKey, TCallBack(splashImageChanged, q)));
       
   122 }
       
   123 
       
   124 HbGlobalStatusBarPrivate::~HbGlobalStatusBarPrivate()
       
   125 {
       
   126     delete mBmpPrt;
       
   127     delete mBmpLsc;
       
   128 }
       
   129 
       
   130 TInt HbGlobalStatusBarPrivate::splashImageChanged(TAny *param)
       
   131 {
       
   132     emit static_cast<HbGlobalStatusBar *>(param)->changed();
       
   133     return 0;
       
   134 }
       
   135 
       
   136 TInt HbGlobalStatusBarPrivate::bitmapHandle(Qt::Orientation orientation)
       
   137 {
       
   138     return orientation == Qt::Vertical ? mPrt->value() : mLsc->value();
       
   139 }
       
   140 
       
   141 CFbsBitmap **HbGlobalStatusBarPrivate::storedBitmap(Qt::Orientation orientation)
       
   142 {
       
   143     return orientation == Qt::Vertical ? &mBmpPrt : &mBmpLsc;
       
   144 }
       
   145 
       
   146 #endif
       
   147 
       
   148 HbGlobalStatusBar::HbGlobalStatusBar(QObject *parent)
       
   149     : QObject(parent), d(0)
       
   150 {
       
   151 #ifdef Q_OS_SYMBIAN
       
   152     d = new HbGlobalStatusBarPrivate(this);
       
   153 #endif
       
   154 }
       
   155 
       
   156 HbGlobalStatusBar::~HbGlobalStatusBar()
       
   157 {
       
   158 #ifdef Q_OS_SYMBIAN
       
   159     delete d;
       
   160 #endif
       
   161 }
       
   162 
       
   163 QImage HbGlobalStatusBar::getImage(Qt::Orientation orientation)
       
   164 {
       
   165 #ifdef Q_OS_SYMBIAN
       
   166     QImage result;
       
   167     TInt handle = d->bitmapHandle(orientation);
       
   168     CFbsBitmap **store = d->storedBitmap(orientation);
       
   169     if (!*store || (*store)->Handle() != handle) {
       
   170         delete *store;
       
   171         *store = 0;
       
   172         CFbsBitmap *bmp = new CFbsBitmap;
       
   173         if (bmp->Duplicate(handle) == KErrNone) {
       
   174             *store = bmp;
       
   175         } else {
       
   176             qWarning("HbGlobalStatusBar: Duplicate() failed for handle %d", handle);
       
   177             delete bmp;
       
   178         }
       
   179     }
       
   180     if (*store) {
       
   181         CFbsBitmap *bmp = *store;
       
   182         // Make a deep copy because the bitmap content may change at any time.
       
   183         uchar *src = reinterpret_cast<uchar *>(bmp->DataAddress());
       
   184         TSize sz = bmp->SizeInPixels();
       
   185         int srcBpl = CFbsBitmap::ScanLineLength(sz.iWidth, bmp->DisplayMode());
       
   186         QImage image(sz.iWidth, sz.iHeight, QImage::Format_ARGB32_Premultiplied);
       
   187         uchar *dst = image.bits();
       
   188         if (srcBpl == image.bytesPerLine() && bmp->DisplayMode() == EColor16MAP) {
       
   189             qMemCopy(dst, src, sz.iHeight * image.bytesPerLine());
       
   190             result = image;
       
   191         } else {
       
   192             qWarning("HbGlobalStatusBar: Bitmap mismatch");
       
   193         }
       
   194     }
       
   195     return result;
       
   196 #else
       
   197     Q_UNUSED(orientation);
       
   198     return QImage();
       
   199 #endif
       
   200 }