diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/screendriver/swins/SCDRAW.INL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/screendriver/swins/SCDRAW.INL Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,235 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "_WININC.H" +#include + +#if defined(SYMBIAN_GRAPHICS_GCE) +#include +#endif //SYMBIAN_GRAPHICS_GCE + +template CScreenDevice::~CScreenDevice() + { + iUpdateRegion.Close(); + iWindowInUse.Close(); + RWindows::ReleaseWindow(iScreenNo); + } + +/** +Constructs the CScreenDevice object. +@param aScreenNo Screen number. It will be used in HAL::Get() calls. +@param aHwnd Windows OS - window handle. +@param aSize Screen size +@return System-wide error codes, KErrNone if the construction was successfull. +*/ +template TInt CScreenDevice::ConstructScreen(TInt aScreenNo, TAny* aHwnd,const TSize& aSize) + { + iScreenNo = aScreenNo; + TInt ret = Construct(aSize); + if (ret != KErrNone) + return ret; + + if (aSize.iWidth < aSize.iHeight) + { + TInt bpp = BitsPerPixel(iDispMode); + delete[] iScanLineBuffer; + TInt scanLineWords = ((iSize.iHeight * bpp) + 31) / 32; + iScanLineBuffer = (TUint32*)(User::Heap().Alloc(scanLineWords * 4)); + if (!iScanLineBuffer) + return KErrNoMemory; + } + + iWindow = RWindows::GetWindow(iScreenNo, aHwnd,aSize); + if (iWindow == NULL) + return KErrNoMemory; + + SetBits(iWindow->EpocBitmapBits()); + //Some explanations about iWindowInUse semaphore. + //On the Emulator, a single Windows OS window can be shared between many Symbian OS + //screen devices. iWindowInUse semaphore is used to help to determine the moment, + //when the related Windows OS window can be destroyed safely. Because it is a named + //semaphore, it will be created once by the first client (Symbian OS screen device) + //and opened (reference counted) by the every next client (Symbian OS screen device). + //In the CScreenDevice's deastructor iWindowInUse semaphore will be closed + //(its reference counter gets decremented). When its value reaches zero, the Symbian OS + //will destroy the semaphore. This action will be detected by the RWindows::ReleaseWindow()'s + //implementation and the related Windows OS window will be destroyed. + TBuf<32> screenSemaphoreName; + ::CreateScreenSemaphoreName(iScreenNo, screenSemaphoreName); + ret = iWindowInUse.CreateGlobal(screenSemaphoreName,0,EOwnerThread); + if (ret == KErrAlreadyExists) + { + iWindowInUse.OpenGlobal(screenSemaphoreName,EOwnerThread); + } + return KErrNone; + } + +template TInt CScreenDevice::HorzTwipsPerThousandPixels() const + { + if (iSize.iWidth==0) + return(0); + TInt twips = 0; + HAL::Get(iScreenNo, HALData::EDisplayXTwips,twips); + return twips * 1000 / iSize.iWidth; + } + +template TInt CScreenDevice::VertTwipsPerThousandPixels() const + { + if (iSize.iHeight==0) + return(0); + TInt twips = 0; + HAL::Get(iScreenNo, HALData::EDisplayYTwips,twips); + return twips * 1000 / iSize.iHeight; + } + +template void CScreenDevice::OrientationsAvailable(TBool aOrientation[4]) + { + aOrientation[EOrientationNormal] = ETrue; + aOrientation[EOrientationRotated90] = ETrue; + aOrientation[EOrientationRotated180] = ETrue; + aOrientation[EOrientationRotated270] = ETrue; + } + +template void CScreenDevice::SetDisplayMode(CFbsDrawDevice* aDrawDevice) + { + iUpdateRegion.Clear(); + SetOrientation(static_cast(iWindow->Orientation())); + CopyOldSettings(aDrawDevice); + InitScreen(); + } + +template void CScreenDevice::SetAutoUpdate(TBool aAutoUpdate) + { + iAutoUpdate = aAutoUpdate; + } + +template void CScreenDevice::SetScreenOrientation(TInt aOrientation) + { + Update(); + + TEmulatorFlip flip = EEmulatorFlipRestore; + switch (aOrientation) + { + case 0: // Already set + break; + case 1: + flip = EEmulatorFlipLeft; + break; + case 2: + flip = EEmulatorFlipInvert; + break; + case 3: + flip = EEmulatorFlipRight; + break; + default: + ASSERT(0); + break; + } + EmulatorFlip(flip, iScreenNo); + iWindow->SetOrientation(aOrientation); + } + +// +// Update the screen with the update region. +// +template void CScreenDevice::Update() + { + if (iUpdateRegion.IsEmpty()) + return; + UpdateScreen(iUpdateRegion); + iUpdateRegion.Clear(); + } + +// +// Update the screen with the union of the update and specified regions. +// aRegion - logical coordinates +template void CScreenDevice::Update(const TRegion& aRegion) + { + if(!aRegion.IsEmpty() && !aRegion.CheckError()) + { + if(iScalingOff && iOriginIsZero) + { + iUpdateRegion.Union(aRegion); + } + else + { + register TInt rcCnt = aRegion.Count(); + RRegion physRegion(rcCnt); + register TInt originX = iOrigin.iX; + register TInt originY = iOrigin.iY; + register TInt factorX = iScalingSettings.iFactorX; + register TInt factorY = iScalingSettings.iFactorY; + for(register TInt i=0;i void CScreenDevice::UpdateRegion(const TRect& aRect) + { + register TInt originX = iOrigin.iX; + register TInt originY = iOrigin.iY; + register TInt factorX = iScalingSettings.iFactorX; + register TInt factorY = iScalingSettings.iFactorY; + TRect physRect; + physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, factorX, iSize.iWidth); + physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, factorY, iSize.iHeight); + physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, factorX, iSize.iWidth); + physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, factorY, iSize.iHeight); + physRect.Normalize(); + iUpdateRegion.AddRect(physRect); + if(iUpdateRegion.Count() >= 10) + { + iUpdateRegion.AddRect(iUpdateRegion.BoundingRect()); + } + if(iAutoUpdate) + { + Update(); + } + } + +template void CScreenDevice::UpdateScreen(const TRegion& aRegion) + { + if (aRegion.CheckError()) + UpdateRect(iSize); + else + for(TInt count = 0; count < aRegion.Count(); count++) + UpdateRect(aRegion[count]); + + iWindow->Update(aRegion,iSize); + } + +template TUint8* CScreenDevice::WinPixelAddress(TInt aX,TInt aY) const + { + return iWindow->PixelAddress(aX,aY); + } +