diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/src/HuiStatic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/coretoolkit/src/HuiStatic.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,1279 @@ +/* +* Copyright (c) 2006-2007 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: Implements CHuiStatic, static data access and utility +* functions such as timing. +* +*/ + + + +#include "uiacceltk/HuiStatic.h" // Class definition +#include "uiacceltk/HuiUtil.h" +#include "uiacceltk/HuiEnv.h" +#include "HuiRenderPlugin.h" +#include "huistatictlsdata.h" +#include "uiacceltk/HuiProbe.h" +#include +#include +#include +#include +#include +#include +#include +#include "alfappfwproxyops.h" + + + +// Global writeable data, used in HW instead of TLS which relatively slow +#ifndef __WINSCW__ +TTlsData globalWriteableData; +#endif + +void CleanupWg(TAny* aWg) + { + RWindowGroup* wg = static_cast(aWg); + delete wg; + } + +/** Dummy implementation for HuiProbe, to be used when external probe is not set */ +NONSHARABLE_CLASS(TFakeProbe) : public MHuiProbe + { +public: + virtual void ReportObjectLifeCycleEvent(const MHuiSessionObject&, TLifecycleEvent) {} + virtual void ReportProgramFlowEvent(TProgramFlowPoint, TProgramFlowEvent) {} + virtual void ReportProgramFlowEvent(const MHuiSessionObject&, TProgramFlowPoint, TProgramFlowEvent) {} + void ReportFrameRate(TInt) const {} + void AssociateWithCurrentSession(MHuiSessionObject&) {} + }; + + +NONSHARABLE_CLASS(CAppFwProxy): public CBase + { +public: + class CAlfLayoutListener: public CActive + { + public: + CAlfLayoutListener(CAppFwProxy& aNotif):CActive(CActive::EPriorityStandard), iNotif(aNotif) + { + CActiveScheduler::Add(this); + iStatus = KErrNotFound; + } + + ~CAlfLayoutListener() + { + Cancel(); + } + + void RunL() + { + iNotif.iLayoutMirrored = (iStatus.Int() > 0); + SetActive(); + TAlfCommandParams params={EAlfIsMirrorred,0,0,0}; + TPckgC pkg(params); + TBuf8<1> awkwardApiDummy; + iNotif.iNotif.StartNotifierAndGetResponse(iStatus,TUid::Uid(KAlfAppFwProxyUid), pkg, awkwardApiDummy); } + + void DoCancel() + { + // just wait for notifier completion + User::WaitForRequest(iStatus); + } + + private: + CAppFwProxy& iNotif; + }; + + CAppFwProxy():iLayoutMirrored(KErrNotFound) + {} + + ~CAppFwProxy() + { + if (iConnected) + { + iNotif.Close(); + delete iLayoutUpdateAo; + } + } + + TBool Connect() + { + if (!iConnected) + { + // perhaps should check also whether eikon server / notifier server exists.. + iConnected = (iNotif.Connect() == KErrNone); + } + return iConnected; + } + + TBool LayoutMirrored() + { + if ( Connect() && iLayoutMirrored == KErrNotFound) + { + TRequestStatus status; + TAlfCommandParams params={EAlfIsMirrorred,0,0,0}; + TPckgC pkg(params); + TBuf8<1> awkwardApiDummy; + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, awkwardApiDummy); + User::WaitForRequest(status); + // order updates + iLayoutUpdateAo = new CAlfLayoutListener(*this); + if (iLayoutUpdateAo) + { + TRAP_IGNORE(iLayoutUpdateAo->RunL()); + } + + iLayoutMirrored = (status.Int() > 0); + } + + return iLayoutMirrored==KErrNotFound?EFalse:iLayoutMirrored; + } + + TInt SoftKeyOrientation() + { + TInt ret = 0; + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams params={EAlfCbaLocation,0,0,0}; + TPckgC pkg(params); + TBuf8<1> awkwardApiDummy; + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, awkwardApiDummy); + User::WaitForRequest(status); + ret = status.Int(); + } + + return ret; + } + + TRect LayoutMetricsRect(TInt aType) + { + TRect ret=TRect(0,0,0,0); + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams params={EAlfLayoutMetricsRect,aType,0,0}; + TPckgC pkg(params); + TPckg retpkg(ret); + + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, retpkg); + User::WaitForRequest(status); + } + + return ret; + } + + TInt GetCachedColor(TRgb& aRgb, const TAknsItemID& aID, + const TInt aIndex ) + { + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams params={EAlfGetCachedColor,aID.iMajor,aID.iMinor,aIndex}; + TPckgC pkg(params); + TPckg retpkg(aRgb); + + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, retpkg); + User::WaitForRequest(status); + return status.Int(); + } + + return KErrCouldNotConnect; + } + + void GetSkinBitmapL(CFbsBitmap* aBitmap, CFbsBitmap* aMask, const TAknsItemID& aID, const TDesC& aFileName, TInt aBitmapId, + TInt aMaskId, const TSize& aSize, TScaleMode aScaleMode) + { + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams2 params={EAlfGetSkinBitmap,aID.iMajor,aID.iMinor,aBitmapId,aMaskId,aFileName, aSize, aScaleMode}; + TPckgC pkg(params); + TInt2 handles = {0,0}; + TPckg retpkg(handles); + + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, retpkg); + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + if (!handles.iInt1) + { + User::Leave(KErrNotFound); + } + User::LeaveIfError(aBitmap->Duplicate(handles.iInt1)); + if ( aMask && handles.iInt2 ) + { + User::LeaveIfError(aMask->Duplicate(handles.iInt2)); + } + } + } + + void GetSkinBackgroundBitmapL(CFbsBitmap* aBitmap, const TAknsItemID& aID ) + { + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams params={EAlfGetSkinBackgroundBitmap,aID.iMajor,aID.iMinor,0}; + TPckgC pkg(params); + TInt handle = 0; + TPckg retpkg(handle); + + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, retpkg); + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + User::LeaveIfError(aBitmap->Duplicate(handle)); + } + } + + void GetCachedSkinItemDataArrayL(const TAknsItemID& aID, TInt aType, TAlfCachedSkinItemArray& aArray) + { + if ( Connect() ) + { + TRequestStatus status; + TAlfCommandParams params={EGetCachedSkinItemData,aID.iMajor,aID.iMinor,aType}; + TPckgC pkg(params); + TPckg retpkg(aArray); + + iNotif.StartNotifierAndGetResponse(status,TUid::Uid(KAlfAppFwProxyUid), pkg, retpkg); + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + } + } + + void GetListOfWindowGroupsL(TRequestStatus& aStatus, TPtr8& aPtr) + { + if ( Connect() ) + { + TAlfCommandParams params={EGetListOfWindowGroups,0,0,0}; + TPckgC pkg(params); + iNotif.StartNotifierAndGetResponse(aStatus,TUid::Uid(KAlfAppFwProxyUid), pkg, aPtr); + } + } + public: + TBool iLayoutMirrored; + RNotifier iNotif; + TBool iConnected; + CAlfLayoutListener* iLayoutUpdateAo; + }; + +CHuiStatic* CHuiStatic::NewLC(CHuiEnv* aPrimaryEnv) + { + CHuiStatic* self = new (ELeave) CHuiStatic(); + CleanupStack::PushL(self); + self->ConstructL(aPrimaryEnv); + return self; + } + + +CHuiStatic* CHuiStatic::NewL(CHuiEnv* aPrimaryEnv) + { + CHuiStatic* self = NewLC(aPrimaryEnv); + CleanupStack::Pop(self); + return self; + } + + +CHuiStatic::CHuiStatic() + { + } + + +void CHuiStatic::ConstructL(CHuiEnv* aPrimaryEnv) + { + iData = new (ELeave) TTlsData(); + + iData->iPrimaryEnv = aPrimaryEnv; + iData->iIdCounter = -1; + iData->iTimeFactor = 1.0; + iData->iIsFirstUpdateTime = ETrue; + iData->iFirstUpdateTime.UniversalTime(); + iData->iUniversalTime.UniversalTime(); + iData->iRealUniversalTime.UniversalTime(); + iData->iLastFpsTime.UniversalTime(); + iData->DoInitL(); // make sure that we have infra even CCoeEnv was not there + + // Re-construct the virtual table for iFakeProbe + iData->iFakeProbe = new (ELeave) TFakeProbe; + + iData->iAppFwProxy = new (ELeave) CAppFwProxy; + + //Register for environment change ( here system time change ) event notification + iChangeNotifier = CEnvironmentChangeNotifier::NewL(0, TCallBack(CHuiStatic::SettingChangedCallBack, this)); + iChangeNotifier->Start(); +#ifndef __WINSCW__ + globalWriteableData = *iData; +#else + Dll::SetTls(iData); +#endif + +#ifndef WIN32 +#ifdef HUI_DEBUG_WITH_PRINTF + EnableLogging(); +#endif +#endif + } + + +CHuiStatic::~CHuiStatic() + { + if(iData) + { + if(iData->iFakeProbe) + { + delete iData->iFakeProbe; + iData->iFakeProbe = NULL; + } + iData->iLogFile.Close(); + delete iData->iAppFwProxy; + iData->Disconnect(); + } + iChangeNotifier->Cancel(); + delete iChangeNotifier; +#ifdef __WINSCW__ + Dll::FreeTls(); +#endif + delete iData; + } + + +EXPORT_C TTlsData* CHuiStatic::Data() + { +#ifndef __WINSCW__ + return &globalWriteableData; +#else + return static_cast(Dll::Tls()); +#endif + } + + +void CHuiStatic::UpdateTime(TTlsData* aData) + { + ASSERT( aData ); + // Updates the toolkit's time counters. This includes the toolkit's + // realtime clock, the internal absolute clock (which is affected by the + // time factor), the amount of elapsed time since last UpdateTime() + // invocation, and the amount of elapsed time since the first UpdateTime() + // invocation (which was done in the beginning of the first refresh). + + if(aData->iIsFirstUpdateTime) + { + aData->iIsFirstUpdateTime = EFalse; + aData->iFirstUpdateTime.UniversalTime(); + aData->iUniversalTime = aData->iFirstUpdateTime; + aData->iRealUniversalTime = aData->iUniversalTime; + return; + } + + TTime now; + now.UniversalTime(); + + // Advance the toolkit's internal clock, applying the time factor. + if(!aData->iTimePaused) + { + aData->iInternalElapsed = now.MicroSecondsFrom(aData->iRealUniversalTime).Int64(); + aData->iInternalElapsed = (TInt64)((TReal32)aData->iInternalElapsed * aData->iTimeFactor); + aData->iUniversalTime += TTimeIntervalMicroSeconds(aData->iInternalElapsed); + } + else + { + aData->iInternalElapsed = aData->iInternalElapsedBeforePausing; + aData->iInternalElapsedBeforePausing = 0; + } + + aData->iRealUniversalTime = now; + } + + +TUint32 CHuiStatic::MilliSecondsSinceUpdateTime() + { + TTlsData* data = Data(); + + TTime now; + now.UniversalTime(); + + return now.MicroSecondsFrom(data->iRealUniversalTime).Int64() / 1000; + } + + +EXPORT_C CHuiEnv& CHuiStatic::Env() + { + if(!Data()) + { + THuiPanic::Panic(THuiPanic::EStaticDataNotCreated); + } + return *Data()->iPrimaryEnv; + } + + +EXPORT_C CHuiRenderPlugin& CHuiStatic::Renderer() + { + if(!Data() || !Data()->iRenderer) + { + HUI_DEBUG(_L("CHuiStatic::Renderer() - Static data or renderer not specified.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *Data()->iRenderer; + } + + +void CHuiStatic::SetRenderer(CHuiRenderPlugin& aRenderer) + { + if(!Data()) + { + THuiPanic::Panic(THuiPanic::EStaticDataNotCreated); + } + Data()->iRenderer = &aRenderer; + } + + +// @TODO SHOULD THIS BE MODIFIED SOMEHOW, OR IS THIS EXPORT OK??? +EXPORT_C CHuiBitgdiRenderPlugin& CHuiStatic::BitgdiRenderer() + { + CHuiRenderPlugin* renderer = &Renderer(); + if(renderer->Id() != EHuiRenderPluginBitgdi) + { + HUI_DEBUG(_L("CHuiStatic::BitgdiRenderer() - Renderer cannot be used as Bitgdi renderer.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *reinterpret_cast< CHuiBitgdiRenderPlugin* >(renderer); + } + + +EXPORT_C CHuiVg10RenderPlugin& CHuiStatic::Vg10Renderer() + { + CHuiRenderPlugin* renderer = &Renderer(); + if(renderer->Id() != EHuiRenderPluginVg10) + { + HUI_DEBUG(_L("CHuiStatic::Vg10Renderer() - Renderer cannot be used as Vg10 renderer.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *reinterpret_cast< CHuiVg10RenderPlugin* >(renderer); + } + + +EXPORT_C CHuiGles10RenderPlugin& CHuiStatic::Gles10Renderer() + { + CHuiRenderPlugin* renderer = &Renderer(); + if(renderer->Id() != EHuiRenderPluginGles10 && + renderer->Id() != EHuiRenderPluginGles11) // compatible + { + HUI_DEBUG(_L("CHuiStatic::Gles10Renderer() - Renderer cannot be used as Gles10 renderer.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *reinterpret_cast< CHuiGles10RenderPlugin* >(renderer); + } + + +EXPORT_C CHuiGles11RenderPlugin& CHuiStatic::Gles11Renderer() + { + CHuiRenderPlugin* renderer = &Renderer(); + if(renderer->Id() != EHuiRenderPluginGles11) + { + HUI_DEBUG(_L("CHuiStatic::Gles11Renderer() - Renderer cannot be used as Gles11 renderer.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *reinterpret_cast< CHuiGles11RenderPlugin* >(renderer); + } + + +EXPORT_C CHuiGles20RenderPlugin& CHuiStatic::Gles20Renderer() + { + CHuiRenderPlugin* renderer = &Renderer(); + if(renderer->Id() != EHuiRenderPluginGles20) + { + HUI_DEBUG(_L("CHuiStatic::Gles20Renderer() - Renderer cannot be used as Gles20 renderer.")); + THuiPanic::Panic(THuiPanic::EStaticInvalidRenderer); + } + return *reinterpret_cast< CHuiGles20RenderPlugin* >(renderer); + } + + +EXPORT_C MHuiRenderSurface* CHuiStatic::CurrentRenderSurface() + { + if(!Data()) + { + HUI_DEBUG(_L("CHuiStatic::CurrentRenderSurface() - Static data or current render surface not specified. Panicking.")); + THuiPanic::Panic(THuiPanic::EStaticCurrentRenderSurfaceNotSpecified); + } + return Data()->iCurrentRenderSurface; + } + + +EXPORT_C void CHuiStatic::SetCurrentRenderSurface(MHuiRenderSurface* aSurface) + { + Data()->iCurrentRenderSurface = aSurface; + } + + +EXPORT_C void CHuiStatic::EnableLogging(TBool aEnable) + { + TTlsData* data = Data(); + + if(aEnable && !data->iLogEnabled) + { + data->iLogEnabled = ETrue; + + // debug code only + TFileName filename; + filename.Append('e'); + filename.Append(':'); + filename.Append('\\'); + filename.Append(_L("HuiMessages.log")); + + if(data->iLogFile.Replace(*data->iFs, filename, EFileWrite) != KErrNone) + { + RDebug::Print(_L("CHuiStatic::EnableLogging() - Could not open log file e:HuiMessages.log for writing. Trying c: ..")); + _LIT(KFileName2, "c:\\HuiMessages.log"); + if(data->iLogFile.Replace(*data->iFs, KFileName2, EFileWrite) != KErrNone) + { + RDebug::Print(_L("CHuiStatic::EnableLogging() - Could not open log file c:HuiMessages.log for writing. Logging disabled.")); + data->iLogEnabled = EFalse; + } + else + { + RDebug::Print(_L("CHuiStatic::EnableLogging() - Enabled Logging to c \"HuiMessages.log\".")); + Printf(_L("CHuiStatic::EnableLogging() - Enabled Logging to \"HuiMessages.log\".")); + } + } + else + { + RDebug::Print(_L("CHuiStatic::EnableLogging() - Enabled Logging to mmc \"HuiMessages.log\".")); + Printf(_L("CHuiStatic::EnableLogging() - Enabled Logging to mmc \"HuiMessages.log\".")); + } + } + else if(!aEnable && data->iLogEnabled) + { + data->iLogFile.Close(); + data->iLogEnabled = EFalse; + } + else + { + // for PC lint + } + } + + +EXPORT_C TBool CHuiStatic::Logging() + { + return Data()->iLogEnabled; + } + + +EXPORT_C void CHuiStatic::ContinueRefresh() + { + TTlsData* data = Data(); + if(data && data->iPrimaryEnv) + { + data->iPrimaryEnv->ContinueRefresh(); + } + } + + +void CHuiStatic::UpdateTime() + { + // Updates the toolkit's time counters. This includes the toolkit's + // realtime clock, the internal absolute clock (which is affected by the + // time factor), the amount of elapsed time since last UpdateTime() + // invocation, and the amount of elapsed time since the first UpdateTime() + // invocation (which was done in the beginning of the first refresh). + + TTlsData* data = Data(); + + UpdateTime(data); + } + + +EXPORT_C const TTime& CHuiStatic::Time() + { + return Data()->iUniversalTime; + } + + +EXPORT_C void CHuiStatic::SetTimeFactor(TReal32 aTimeFactor) __SOFTFP + { + TTlsData* data = Data(); + + if(data) + { + if(aTimeFactor < 0) + { + aTimeFactor = 0; + } + + if(data->iTimeFactor == 0 && aTimeFactor != 0) + { + // Continuing from a paused state + UpdateTime(data); + } + + data->iTimeFactor = aTimeFactor; + } + } + + +EXPORT_C TReal32 CHuiStatic::TimeFactor() __SOFTFP + { + TTlsData* data = Data(); + + if(data) + { + return data->iTimeFactor; + } + return 1.0; + } + + +EXPORT_C void CHuiStatic::PauseTime() + { + TTlsData* data = Data(); + + if(data) + { + // Update internal elapsed + UpdateTime(data); + // Cache internal elapsed in internal time passed before pausing + data->iInternalElapsedBeforePausing = data->iInternalElapsed; + // Pause timing + data->iTimePaused = ETrue; + } + } + + +EXPORT_C void CHuiStatic::ContinueTime() + { + TTlsData* data = Data(); + + if(data && data->iTimePaused) + { + UpdateTime(data); + data->iTimePaused = EFalse; + } + } + + +EXPORT_C TBool CHuiStatic::TimePaused() + { + TTlsData* data = Data(); + + if(data) + { + return data->iTimePaused; + } + return EFalse; + } + + +EXPORT_C TReal32 CHuiStatic::ElapsedSeconds() __SOFTFP + { + TTlsData* data = Data(); + + if(data) + { +#ifdef EKA2 + return data->iInternalElapsed / 1.0e6; +#else + return data->iInternalElapsed.GetTReal() / 1.0e6; +#endif + } + return 0; + } + + +EXPORT_C TReal32 CHuiStatic::SecondsSinceStart() __SOFTFP + { + TTlsData* data = Data(); + if(!data) + { + // Time has not begun yet. + return 0; + } + + // Calculate difference between internal absolute clock and the first update time. + TInt64 delta = data->iUniversalTime.MicroSecondsFrom(data->iFirstUpdateTime).Int64(); +#ifdef EKA2 + return delta / 1.0e6; +#else + return delta.GetTReal() / 1.0e6; +#endif + } + + +EXPORT_C TUint32 CHuiStatic::MilliSecondsSinceStart() + { + // This will wrap around in approx. 50 days. + TTlsData* data = Data(); + if(data) + { + // Calculate difference between internal absolute clock and the first update time. + TInt64 delta = data->iUniversalTime.MicroSecondsFrom(data->iFirstUpdateTime).Int64(); + return delta / 1000; + } + return 0; + + } + + +TInt CHuiStatic::GenerateId() + { + TTlsData* data = Data(); + + // The ID counter counts backwards. + TInt id = data->iIdCounter; + + if(data->iIdCounter == KMinTInt) + { + // Wrap around to stay negative. + data->iIdCounter = -1; + } + else + { + --data->iIdCounter; + } + + return id; + } + + +void CHuiStatic::ReportNewFrame() + { + TTlsData* data = Data(); + data->iFrameCounter++; + data->iCurrentFrameCounter++; + } + + +EXPORT_C TUint CHuiStatic::FrameCount() + { + TTlsData* data = Data(); + return data->iFrameCounter; + } + + +EXPORT_C TReal32 CHuiStatic::AverageFrameRate() __SOFTFP + { + return 0; + } + + +EXPORT_C TReal32 CHuiStatic::FrameRate() __SOFTFP + { + + TTlsData* data = Data(); + + TTime now; + now.UniversalTime(); + + // If very little time has passed, don't calculate a new value yet. + TTimeIntervalMicroSeconds msFromLast = 0; + msFromLast = now.MicroSecondsFrom(data->iLastFpsTime); + if(msFromLast < TTimeIntervalMicroSeconds(TInt64(1e6))) + { + // Do not recalculate yet. +#ifdef SYMBIAN_BUILD_GCE + return 0; // to ignore the value if time is not elapsed +#else + return data->iLastFps; +#endif + } + + if(data->iCurrentFrameCounter == 0) + { + data->iLastFpsTime = now; + return 0; + } + + TInt64 delta = now.MicroSecondsFrom(data->iLastFpsTime).Int64(); + + TReal32 fps = 0; +#ifdef EKA2 + TReal32 elapsed = delta / 1.0e6; +#else + TReal32 elapsed = delta.GetTReal() / 1.0e6; +#endif + + if(elapsed > 0) + { + fps = (TReal32)data->iCurrentFrameCounter / elapsed; + } + + data->iLastFps = fps; + data->iCurrentFrameCounter = 0; + data->iLastFpsTime = now; + + return fps; + } + + +EXPORT_C void CHuiStatic::Printf(TRefByValue aFormat, ...) + { + TTlsData* data = Data(); + // Bail out early if logging is disabled. + if(!data || !data->iLogEnabled) + { +#ifdef _DEBUG + // redirect to RDebug output if we are debugging + TUint total = 0; + TUint free = HuiUtil::FreeMemory(&total); + TBuf8<256> buf; + VA_LIST list; + VA_START(list, aFormat); + buf.FormatList(aFormat, list); + VA_END(list); + RDebug::Print(_L("(%i/%i KB) %s"), free/1024, total/1024, &buf); +#endif + // Already gone? + return; + } + TTime now; + now.UniversalTime(); + TInt32 elapsed = (TInt32)(now.MicroSecondsFrom(data->iFirstUpdateTime).Int64() / 1000); + + TBuf8<100> memData; + TUint total = 0; + TUint free = HuiUtil::FreeMemory(&total); + memData.Format(_L8("% 2d,%03d (%i/%i KB) "), elapsed / 1000, + elapsed % 1000, + free/1024, total/1024); + + TBuf8<512> buf; + VA_LIST list; + VA_START(list, aFormat); + buf.FormatList(aFormat, list); + VA_END(list); + buf.Insert(0, memData); + buf.Append(_L8("\n")); + + data->iLogFile.Write(buf); + data->iLogFile.Flush(); + } + + +EXPORT_C void CHuiStatic::Printf(TRefByValue aFormat, ...) + { + TTlsData* data = Data(); + // Bail out early if logging is disabled. + if(!data || !data->iLogEnabled) + { +#ifdef _DEBUG + // redirect to RDebug output if we are debugging + TBuf16<512> buf; + TUint total; TUint free = HuiUtil::FreeMemory(&total); + VA_LIST list; + VA_START(list, aFormat); + buf.FormatList(aFormat, list); + VA_END(list); + RDebug::Print(_L("(%i/%i KB) %S"), free/1024, total/1024, &buf); +#endif + // Already gone? + return; + } + TTime now; + now.UniversalTime(); + TInt32 elapsed = (TInt32)(now.MicroSecondsFrom(data->iFirstUpdateTime).Int64() / 1000); + + TBuf16<100> memData; + TUint total = 0; + TUint free = HuiUtil::FreeMemory(&total); + memData.Format(_L16("% 2d,%03d (%i/%i KB) "), elapsed / 1000, + elapsed % 1000, + free/1024, total/1024); + + TBuf16<512> buf; + VA_LIST list; + VA_START(list, aFormat); + buf.FormatList(aFormat, list); + VA_END(list); + buf.Insert(0, memData); + buf.Append(_L16("\n")); + + TBuf8<512> buf8; + buf8.SetLength(buf.Length()); + for(TInt i = 0; i < buf.Length(); ++i) + { + buf8[i] = TUint8(buf[i]); + } + + data->iLogFile.Write(buf8); + data->iLogFile.Flush(); + } + + +EXPORT_C void CHuiStatic::Tic(TInt aClock) + { + if(aClock < 0 || aClock >= KMaxClocks) + { + THuiPanic::Panic(THuiPanic::EStaticInvalidClock); + } + + TTlsData* data = Data(); + data->iClocks[aClock].UniversalTime(); + } + + +EXPORT_C TReal32 CHuiStatic::Toc(TInt aClock) __SOFTFP + { + if(aClock < 0 || aClock >= KMaxClocks) + { + THuiPanic::Panic(THuiPanic::EStaticInvalidClock); + } + + TTlsData* data = Data(); + + TTime now; + now.UniversalTime(); + + TInt64 delta = now.MicroSecondsFrom(data->iClocks[aClock]).Int64(); +#ifdef EKA2 + return delta / 1.0e6; +#else + return delta.GetTReal() / 1.0e6; +#endif + } + + +EXPORT_C RFs& CHuiStatic::FsSession() + { + TTlsData* data = Data(); + __ASSERT_ALWAYS(data, User::Panic(_L("HUI"),0)); + return *data->iFs; + } + +EXPORT_C RWsSession& CHuiStatic::WsSession() + { + TTlsData* data = Data(); + __ASSERT_ALWAYS(data, User::Panic(_L("HUI"),0)); + return *data->iWsSession; + } + +EXPORT_C CWsScreenDevice* CHuiStatic::ScreenDevice( TInt aScreenNumber ) + { + TTlsData* data = Data(); + __ASSERT_ALWAYS(data, User::Panic(_L("HUI"),0)); + return data->WsScreenDevice(aScreenNumber); + } + +EXPORT_C RWindowGroup* CHuiStatic::RootWin( TInt aScreenNumber ) + { + TTlsData* data = Data(); + __ASSERT_ALWAYS(data, User::Panic(_L("HUI"),0)); + return data->RootWin(aScreenNumber); + } + +EXPORT_C void CHuiStatic::SetLayoutTransitionTime( TInt aTime ) + { + TTlsData* data = Data(); + if(data) + { + data->iLayoutTransitionTime = aTime; + } + } + + +EXPORT_C TInt CHuiStatic::LayoutTransitionTime() + { + TTlsData* data = Data(); + if(data) + { + return data->iLayoutTransitionTime; + } + return 0; + } + +EXPORT_C void CHuiStatic::SetProbe(MHuiProbe* aProbe) + { + TTlsData* data = Data(); + if(data) + { + data->iProbe = aProbe; + } + } + +MHuiProbe& CHuiStatic::Probe() + { + TTlsData* data = Data(); + + if ( !data ) + { + THuiPanic::Panic(THuiPanic::EStaticDataNotCreated); + } + + if(data->iProbe) + { + return *(data->iProbe); + } + return *(data->iFakeProbe); + } + +EXPORT_C MAknsSkinInstance* CHuiStatic::SkinInstance() + { + if (CCoeEnv::Static()) + { + return AknsUtils::SkinInstance(); + } + return 0; + } + +TBool CHuiStatic::LayoutMirrored() + { + if (CCoeEnv::Static()) + { + return AknLayoutUtils::LayoutMirrored(); + } + else + { + TTlsData* data = Data(); + return data->iAppFwProxy->LayoutMirrored(); + } + } + +TInt CHuiStatic::CbaLocation() + { + if (CCoeEnv::Static()) + { + return AknLayoutUtils::CbaLocation(); + } + else + { + TTlsData* data = Data(); + return data->iAppFwProxy->SoftKeyOrientation(); + } + } + +void CHuiStatic::LayoutMetricsRect(TInt aType, TRect& aRect) + { + if (CCoeEnv::Static()) + { + (void)AknLayoutUtils::LayoutMetricsRect((AknLayoutUtils::TAknLayoutMetrics)aType, aRect); + } + else + { + TTlsData* data = Data(); + aRect = data->iAppFwProxy->LayoutMetricsRect(aType); + } + } + +TInt CHuiStatic::GetCachedColor(TRgb& aRgb, const TAknsItemID& aID, + const TInt aIndex ) + { + MAknsSkinInstance* skin = SkinInstance(); + if (skin) + { + return AknsUtils::GetCachedColor(skin, aRgb, aID, aIndex ); + } + else + { + TTlsData* data = Data(); + return data->iAppFwProxy->GetCachedColor(aRgb, aID, aIndex ); + } + } + +TBool CHuiStatic::ConvertToVisualAndClipL( + TDes& aLogicalText, + const CFont& aFont, + TInt aMaxWidthInPixels, + TInt aMaxClippedWidthInPixels ) + { + if (CCoeEnv::Static()) + { + return AknBidiTextUtils::ConvertToVisualAndClipL( + aLogicalText, + aFont, + aMaxWidthInPixels, + aMaxClippedWidthInPixels ); + } + else + { + if ( !aLogicalText.Length() ) + { + aLogicalText = KNullDesC; // null text + return EFalse; + } + + HBufC* visualBuffer = HBufC::NewLC( + aLogicalText.Length() + KAknBidiExtraSpacePerLine ); + + TPtr ptr = visualBuffer->Des(); + + TInt chars = aLogicalText.Length(); + + TBool clipped = EFalse; + + TChar clipChar = 0xffff; + + // TextCount() converts text to visual form and then checks it + if ( aFont.TextCount( aLogicalText, aMaxWidthInPixels ) < chars ) + { + clipped = ETrue; + + TInt clipCharWidth = 0; + // Not enough space even for clip char alone - return empty descriptor. + if ( aMaxClippedWidthInPixels < clipCharWidth ) + { + aLogicalText = KNullDesC; // null text + CleanupStack::PopAndDestroy(); // visual buf + return ETrue; + } + + // Check how many characters fit in given space with truncation char. + // We need to give this information to TBidiLogicalToVisual. + chars = aFont.TextCount( + aLogicalText, aMaxClippedWidthInPixels - clipCharWidth ); + + // This is "avkon rule": should not insert ellipsis right after a space. + if ( chars > 1 && + aLogicalText[chars - 1] == ' ' && + aLogicalText[chars - 2] != ' ' ) + { + chars--; + } + } + + TBidirectionalState::TRunInfo* array = + new TBidirectionalState::TRunInfo[chars]; + + TBidiLogicalToVisual converter( + aLogicalText, + array, + chars ) ; + + TInt count = converter.Reorder(); + + if (count > chars) + { + delete array; + array = 0; + array = new TBidirectionalState::TRunInfo[chars]; + } + + if (array) + { + TBidiLogicalToVisual converter = TBidiLogicalToVisual( aLogicalText, array, chars ); + converter.Reorder(); + TPtr ptr = visualBuffer->Des(); + converter.GetVisualLine( ptr, 0, chars, clipChar ); + } + + aLogicalText = *visualBuffer; + + CleanupStack::PopAndDestroy(); + return clipped; + } + } + +HBufC* CHuiStatic::ConvertToVisualAndWrapToArrayL( + const TDesC& aLogicalText, + TInt aLineWidth, + const CFont& aFont, + CArrayFix& aWrappedArray ) + { + if (CCoeEnv::Static()) + { + return AknBidiTextUtils::ConvertToVisualAndWrapToArrayL( + aLogicalText, + aLineWidth, + aFont, + aWrappedArray); + } + else + { + // will not be supported ever + HBufC* ret = aLogicalText.AllocLC(); + aWrappedArray.AppendL(ret->Des()); + CleanupStack::Pop(); + return ret; + } + } + +CFbsBitmap* CHuiStatic::GetBgBitmapLC(const TAknsItemID& aID) + { + CFbsBitmap * bitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(bitmap); + + TTlsData* data = Data(); + data->iAppFwProxy->GetSkinBackgroundBitmapL(bitmap, aID); + + return bitmap; + } + +void CHuiStatic::GetMaskedBitmapL(const TAknsItemID& aID, CFbsBitmap*& aBitmap, CFbsBitmap*& aBitmapMask, + const TDesC& aFileName, TInt aBitmapId, TInt aMaskId, const TSize& aSize, TScaleMode aScaleMode) + { + CFbsBitmap * bitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(bitmap); + + CFbsBitmap * mask = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(mask); + + TTlsData* data = Data(); + data->iAppFwProxy->GetSkinBitmapL(bitmap, mask, aID, aFileName, aBitmapId, aMaskId, aSize, aScaleMode ); + + // Transfer the ownership + if (mask->Handle()) + { + aBitmapMask = mask; + CleanupStack::Pop(); //mask + } + else + { + CleanupStack::PopAndDestroy(); //mask + } + aBitmap = bitmap; + CleanupStack::Pop(); //bitmap + } + +CAknsItemData* CHuiStatic::GetCachedSkinItemDataL(const TAknsItemID& aID, TInt aDataType) + { + CAknsImageTableItemData* skindata = 0; + if (aDataType == EAknsITImageTable) // only image table for framebrush supported + { + TTlsData* data = Data(); + TAlfCachedSkinItemArray array; + data->iAppFwProxy->GetCachedSkinItemDataArrayL(aID, aDataType, array); + if (array.iCount) + { + skindata = CAknsImageTableItemData::NewL(); + CleanupStack::PushL(skindata); + skindata->SetImagesL(array.iCount, array.iImages); + CleanupStack::Pop(); + } + } + return skindata; + } + +TInt CHuiStatic::SettingChangedCallBack(TAny* aInstance) + { + return ((CHuiStatic *)aInstance)->DoChange(); + } + +TInt CHuiStatic::DoChange() + { + TInt change = iChangeNotifier->Change(); + TTlsData* data = Data(); + if(!data) + { + // Time has not begun yet. + return 0; + } + if (change & EChangesLocale) + { + data->iIsFirstUpdateTime = ETrue; + UpdateTime(); + } + + if (change & EChangesSystemTime) + { + data->iIsFirstUpdateTime = ETrue; + UpdateTime(); + } + + return 1; + }