sl@0: // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "offscreenbitmap.h" sl@0: #include "inifile.h" sl@0: #include "panics.h" sl@0: #include "ScrDev.H" sl@0: #include "server.h" sl@0: #include "wstop.h" sl@0: #include "rootwin.h" sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: #include "../../debuglog/osbwin.h" sl@0: #endif sl@0: sl@0: GLREF_D TDisplayMode ParseDisplayMode(const TDesC& aModeName); sl@0: sl@0: CWsOffScreenBitmap* CWsOffScreenBitmap::NewL(CScreen* aScreen) sl@0: { sl@0: CWsOffScreenBitmap* self=new(ELeave) CWsOffScreenBitmap(aScreen); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: inline CWsOffScreenBitmap::CWsOffScreenBitmap(CScreen* aScreen) :iScreen(aScreen) sl@0: {} sl@0: sl@0: CWsOffScreenBitmap::~CWsOffScreenBitmap() sl@0: { sl@0: delete iBitmapGc; sl@0: delete iBitmap; sl@0: iObserver = NULL; sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: delete iOsbWin; sl@0: #endif sl@0: delete iBitmapDevice; sl@0: } sl@0: sl@0: template <class T> sl@0: LOCAL_C inline void Swap(T& aLeft, T& aRight) sl@0: { T temp=aLeft;aLeft=aRight;aRight=temp;} sl@0: template <class T> sl@0: LOCAL_C inline TBool SwapIfLeftIsBigger(T& aLeft, T& aRight) sl@0: {if (aLeft>aRight) { ::Swap(aLeft, aRight); return (aRight>aLeft);} return (aLeft>aRight);} sl@0: sl@0: void CWsOffScreenBitmap::ConstructL() sl@0: { sl@0: _LIT(KFlickerBufferMode,"FLICKERBUFFERMODE"); sl@0: TPtrC flickerBufferModeName; sl@0: TDisplayMode displayMode = ENone; sl@0: if (WsIniFile->FindVar(iScreen->ScreenNumber(), KFlickerBufferMode, flickerBufferModeName)) sl@0: displayMode = ParseDisplayMode(flickerBufferModeName); sl@0: if (displayMode == ENone) sl@0: displayMode = iScreen->DisplayMode(); sl@0: sl@0: WS_ASSERT_DEBUG(displayMode!=ENone, EWsPanicNoDisplayModeFound); sl@0: iBitmap=new(ELeave) CFbsBitmap; sl@0: TSize screenSize=iScreen->ScreenDevice()->SizeInPixels(); sl@0: TBool haveSwapped=SwapIfLeftIsBigger(screenSize.iWidth, screenSize.iHeight); sl@0: User::LeaveIfError(iBitmap->Create(screenSize,displayMode)); sl@0: if (haveSwapped) sl@0: { sl@0: iBitmap->SwapWidthAndHeight(); sl@0: } sl@0: User::LeaveIfError(iBitmap->SetDisplayMode(iScreen->DisplayMode())); sl@0: iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap); sl@0: User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapGc)); sl@0: sl@0: TSizeMode sizeMode = iScreen->ScreenSizeModeData(iScreen->ScreenSizeMode()); sl@0: TSize osbSize(iBitmap->SizeInPixels()); sl@0: TSize osbTwips(sizeMode.iScreenTwipsSize); sl@0: if (osbSize!=sizeMode.iScreenSize) sl@0: { sl@0: // The specified screen twips size is for the specified screen pixel size, however the OSB sl@0: // is potentially larger as it needs to hold the maximum possible screen size, so we need sl@0: // to scale the twips size up correspondingly. sl@0: osbTwips.iWidth=sizeMode.iScreenTwipsSize.iWidth*osbSize.iWidth/sizeMode.iScreenSize.iWidth; sl@0: osbTwips.iHeight=sizeMode.iScreenTwipsSize.iHeight*osbSize.iHeight/sizeMode.iScreenSize.iHeight; sl@0: } sl@0: iBitmap->SetSizeInTwips(osbTwips); sl@0: sl@0: # if defined(__WINS__) && defined(_DEBUG) sl@0: _LIT(KDebugOsb,"DEBUGOSB"); sl@0: if (WsIniFile->FindVar(iScreen->ScreenNumber(),KDebugOsb)) sl@0: { sl@0: _LIT(KDebugOsbTitleFormat, "Screen %d, offscreen bitmap"); sl@0: TBuf<32> title; sl@0: title.Format(KDebugOsbTitleFormat, iScreen->ScreenNumber()); sl@0: iOsbWin = CDebugOsbWin::NewL(title, iBitmap->SizeInPixels()); sl@0: } sl@0: # endif sl@0: } sl@0: sl@0: TInt CWsOffScreenBitmap::DisplayModeChanged(TBool aSwapWidthAndHeight) sl@0: { sl@0: TInt err=KErrNone; sl@0: if (aSwapWidthAndHeight) sl@0: { sl@0: err=iBitmapDevice->SwapWidthAndHeight(); sl@0: WS_ASSERT_DEBUG(err==KErrNone, EWsCreatedOffScreenBitmapInWrongDimensions); sl@0: iBitmapGc->Activate(iBitmapDevice); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void CWsOffScreenBitmap::SetObserver(MWsFlickerFreeBufferObserver* aObserver) sl@0: { sl@0: iObserver = aObserver; sl@0: } sl@0: sl@0: MWsFlickerFreeBufferObserver * CWsOffScreenBitmap::Observer() sl@0: { sl@0: return iObserver; sl@0: } sl@0: sl@0: CFbsBitmap* CWsOffScreenBitmap::Bitmap() sl@0: { sl@0: CFbsBitmap* bmp = iRedirectBuffer? iRedirectBuffer->GetBitmap() : iBitmap; sl@0: WS_ASSERT_DEBUG(bmp!=NULL, EWsPanicTemp); sl@0: return bmp; sl@0: } sl@0: sl@0: CFbsDevice* CWsOffScreenBitmap::BitmapDevice() sl@0: { sl@0: CFbsDevice* device = static_cast<CFbsDevice*>(GetBitGcCurrent()->Device()); sl@0: WS_ASSERT_DEBUG(device!=NULL, EWsPanicNullDeviceHandle); sl@0: return device; sl@0: } sl@0: sl@0: // This function updates the OffScreenBitmap and TransparencyManager's device and GC sl@0: // Note: Here the OffScreenBitmap's scale is not considered. sl@0: void CWsOffScreenBitmap::UpdateGc(const TBool aSwapWidthAndHeight) sl@0: { sl@0: if (aSwapWidthAndHeight) sl@0: { sl@0: iBitmapDevice->SwapWidthAndHeight(); sl@0: } sl@0: iBitmapDevice->SetScalingFactor(iScreen->CurrentScreenModeScaledOrigin(),1,1,1,1); sl@0: iBitmapGc->Activate(iBitmapDevice); sl@0: } sl@0: sl@0: #if defined(__WINS__) && defined(_DEBUG) sl@0: void CWsOffScreenBitmap::Update() sl@0: { sl@0: if (iOsbWin) sl@0: { sl@0: iBitmap->LockHeap(); sl@0: iOsbWin->Refresh(iBitmap->SizeInPixels(), iBitmap->DisplayMode(), iBitmap->DataAddress()); sl@0: iBitmap->UnlockHeap(); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: /** sl@0: Implementing MWsBackBuffer interface sl@0: */ sl@0: CFbsBitmap* CWsOffScreenBitmap::GetBitmap() sl@0: { sl@0: return iBitmap; sl@0: } sl@0: sl@0: CFbsBitGc* CWsOffScreenBitmap::GetBitGc() sl@0: { sl@0: return iBitmapGc; sl@0: } sl@0: sl@0: CFbsBitGc* CWsOffScreenBitmap::GetBitGcCurrent() sl@0: { sl@0: CFbsBitGc* gc = iRedirectGc? iRedirectGc : (iRedirectBuffer? iRedirectBuffer->GetBitGc() : iBitmapGc); sl@0: WS_ASSERT_DEBUG(gc!=NULL, EWsPanicTemp); sl@0: return gc; sl@0: } sl@0: sl@0: TInt CWsOffScreenBitmap::SetBitGc(CFbsBitGc* aBitGc) sl@0: { sl@0: if (iRedirectBuffer) sl@0: return KErrInUse; sl@0: sl@0: if (aBitGc && (aBitGc==iBitmapGc || aBitGc==iRedirectGc)) sl@0: return KErrAlreadyExists; sl@0: sl@0: if (aBitGc && !aBitGc->Device()) sl@0: return KErrArgument; sl@0: sl@0: iRedirectGc = aBitGc; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CWsOffScreenBitmap::RedirectTo(MWsBackBuffer* aTarget) sl@0: { sl@0: if (iRedirectGc) sl@0: return KErrInUse; sl@0: sl@0: if (aTarget && aTarget==iRedirectBuffer) sl@0: return KErrAlreadyExists; sl@0: sl@0: if ( aTarget && iScreen->HasVisibleDirectOnQueue() ) sl@0: return KErrInUse; sl@0: if (aTarget && sl@0: ( sl@0: !aTarget->GetBitmap()|| sl@0: !aTarget->GetBitGc() || sl@0: (aTarget->GetBitGc() && !aTarget->GetBitGc()->Device()) sl@0: ) sl@0: ) sl@0: return KErrArgument; sl@0: sl@0: iRedirectBuffer = aTarget; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TAny* CWsOffScreenBitmap::ResolveObjectInterface(TUint aTypeId) sl@0: { sl@0: switch (aTypeId) sl@0: { sl@0: case MWsBackBuffer::EWsObjectInterfaceId: sl@0: return static_cast<MWsBackBuffer *>(this); sl@0: } sl@0: return NULL; sl@0: }