diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknLayoutConfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/AknLayoutConfig.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,806 @@ +/* +* Copyright (c) 2005 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: Layout configuration data retrieval and access +* +*/ + + +#include "AknLayoutConfig.h" +#include +#include +#include +#include +#include +#include "AknLib.h" +#include +#include "AknLayoutConfigInternal.h" +#include +#include + +NONSHARABLE_CLASS(CAknLayoutConfigWsiniParser) : public CBase + { +public: + static void GetConfigL(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray); + +private: + CAknLayoutConfigWsiniParser(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray); + ~CAknLayoutConfigWsiniParser(); + void GetConfigL(); + HBufC* GetWsiniLC(); + void ParseWsiniL(const TDesC& aWsini); + void ParseLineL(const TText* aKwStart, const TText* aKwEnd, const TText* aLineEnd); + + SHardwareStateInfo& HardwareStateL(TInt aStateNumber); + SAknScreenModeInfo& ScreenModeL(TInt aScreenMode); + TInt ParseIntL(TPtrC& aLine); + TInt ParseKeycodeL(TPtrC& aLine); + TAknPrivSoftkeyLocation ParseSoftkeyLocationL(TPtrC& aLine); + TInt ScreenStyleHash(TPtrC& aLine); + +private: +#define WSINI_PARSE_FUNC(name) static void Call##name(CAknLayoutConfigWsiniParser* aSelf, TPtrC& aLine) { aSelf->name(aLine); } void name(TPtrC& aLine); + WSINI_PARSE_FUNC(HardwareStateKeycodeL) + WSINI_PARSE_FUNC(HardwareStateScreenModeL) + WSINI_PARSE_FUNC(HardwareStateAltScreenModeL) + WSINI_PARSE_FUNC(ScreenModeSoftkeyLocationL) + WSINI_PARSE_FUNC(ScreenModeStyleNameL) + +private: + struct SParseEntry + { + const TText16* iKeyword; + TInt iKeywordLen; + void (*iFunc)(CAknLayoutConfigWsiniParser* aSelf, TPtrC& aLine); + }; + static const SParseEntry iParseTable[]; + +private: + SAknLayoutConfig& iConfig; + RArray& iScreenInfoArray; + RArray& iHardwareStateArray; + }; + +// +// CAknLayoutConfig::TScreenMode +// +EXPORT_C const TPixelsTwipsAndRotation& CAknLayoutConfig::TScreenMode::PixelsTwipsAndRotation() const + { + return iInfo.iPixelsTwipsAndRotation; + } + +CAknLayoutConfig::TScreenMode::TScreenMode(const SAknScreenModeInfo& aInfo) +: TAknScreenMode(aInfo) + { + } + +EXPORT_C TAknPrivSoftkeyLocation CAknLayoutConfig::TScreenMode::SoftkeyLocation() const + { + return iInfo.iSoftkeyLocation; + } + +EXPORT_C TInt CAknLayoutConfig::TScreenMode::ScreenStyleHash() const + { + return iInfo.iScreenStyleHash; + } + + +// +// CAknLayoutConfig::TScreenModeArray +// +EXPORT_C CAknLayoutConfig::TScreenMode CAknLayoutConfig::TScreenModeArray::At(TInt aIndex) const + { + __ASSERT_ALWAYS(0 <= aIndex && aIndex < iInfo.iNumScreenModes, Panic(EAknPanicLayoutConfigBadScreenModeIndex)); + return TScreenMode(iInfo.iScreenModes[aIndex]); + } + +EXPORT_C CAknLayoutConfig::TScreenMode CAknLayoutConfig::TScreenModeArray::Find(TInt aModeNumber) const + { + for (TInt ii=0; iiConstructL(configBuf); + CleanupStack::Pop(self); + return self; + } + +#define UNPACK_CHECK(b) __ASSERT_ALWAYS(b, Panic(EAknPanicLayoutConfigUnpackFail)) + +void CAknLayoutConfig::ConstructL(HBufC8* aBuf) + { + iBuf = aBuf; + + // unpack & validate data + TInt size = iBuf->Size(); + // basic structure + UNPACK_CHECK(size >= sizeof(SAknLayoutConfig)); + iData = (SAknLayoutConfig*)iBuf->Ptr(); + + // check total size + UNPACK_CHECK( + size == + ( + sizeof(SAknLayoutConfig) + + (iData->iNumScreenModes * sizeof(SAknScreenModeInfo)) + + (iData->iNumHardwareStates * sizeof(SHardwareStateInfo)) + )); + + // check and unpack screen modes, iScreenModes is an offset before unpacking + UNPACK_CHECK((TUint32)iData->iScreenModes == sizeof(SAknLayoutConfig)); + iData->iScreenModes = (SAknScreenModeInfo*)((TUint8*)iData + (TUint32)iData->iScreenModes); + + // check iNumScreenModes (we've already checked it fits in size) + UNPACK_CHECK(iData->iNumScreenModes >= 0); + + // check and unpack hardware states, iHardwareStates is an offset before unpacking + UNPACK_CHECK((TUint32)iData->iHardwareStates == (sizeof(SAknLayoutConfig) + sizeof(SAknScreenModeInfo)*iData->iNumScreenModes)); + iData->iHardwareStates = (SHardwareStateInfo*)((TUint8*)iData + (TUint32)iData->iHardwareStates); + + // check iNumHardwareStates (we've already checked it fits in size) + UNPACK_CHECK(iData->iNumHardwareStates >= 0); + } + +HBufC8* CAknLayoutConfig::CreatePackedBufL() + { + // set up structures to collect the config info + SAknLayoutConfig config = { 0, NULL, 0, NULL }; + + RArray screenInfoArray; + CleanupClosePushL(screenInfoArray); + + RArray hardwareStateArray; + CleanupClosePushL(hardwareStateArray); + + // get the config info + TRAP_IGNORE(GetConfigL(config, screenInfoArray, hardwareStateArray)); + + // calculate how much space is needed for the config info + TInt screenModesSize = sizeof(SAknScreenModeInfo) * screenInfoArray.Count(); + TInt hardwareStatesSize = sizeof(SHardwareStateInfo) * hardwareStateArray.Count(); + TInt bufSize = sizeof(SAknLayoutConfig) + screenModesSize + hardwareStatesSize; + + // create the buffer space + HBufC8* buf = HBufC8::NewLC(bufSize); + TPtr8 des(buf->Des()); + + // pack the info for transport + config.iScreenModes = (SAknScreenModeInfo*)sizeof(SAknLayoutConfig); + config.iHardwareStates = (SHardwareStateInfo*)(sizeof(SAknLayoutConfig) + screenModesSize); + + // put the info into the buffer + des.Append(TPckgC(config)); + if (screenModesSize) + des.Append(TPtrC8((TText8*)&screenInfoArray[0], screenModesSize)); + if (hardwareStatesSize) + des.Append(TPtrC8((TText8*)&hardwareStateArray[0], hardwareStatesSize)); + + // tidy up and return + CleanupStack::Pop(buf); + CleanupStack::PopAndDestroy(2); // hardwareStateArray and screenInfoArray + + return buf; + } + +#ifdef _DEBUG +void DebugLayoutConfigLeaves(TAny*) + { + User::Panic(_L("LayoutConfigLeave"), 0); + } +#endif + +void CAknLayoutConfig::GetConfigL(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray) + { +#ifdef _DEBUG + CleanupStack::PushL(TCleanupItem(DebugLayoutConfigLeaves, 0)); +#endif + + CEikonEnv* eikonEnv = CEikonEnv::Static(); + CResourceFile* resFile = CResourceFile::NewLC(eikonEnv->FsSession(), CAknLibrary::PrivateResourceFile(), 0, 0); + resFile->ConfirmSignatureL(); + + TAknPrivSoftkeyLocation landscapeSofkey = GetLandscapeSoftkeyLocationFromAknPrivL(resFile); + GetScreenModesFromWservL(aConfig, aScreenInfoArray, landscapeSofkey); + + CAknLayoutConfigWsiniParser::GetConfigL(aConfig, aScreenInfoArray, aHardwareStateArray); + if (aHardwareStateArray.Count() == 0) + { + // got no info from wsini, so look up AknPriv + GetScreenMapFromAknPrivL(resFile, aScreenInfoArray, aHardwareStateArray); + GetKeyMapFromAknPrivL(resFile, aHardwareStateArray); + } + aConfig.iNumHardwareStates = aHardwareStateArray.Count(); + + CleanupStack::PopAndDestroy(resFile); + +#ifdef _DEBUG + CleanupStack::Pop(); // TCleanupItem(DebugLayoutConfigLeaves, 0) +#endif + } + +void CAknLayoutConfig::GetScreenMapFromAknPrivL(CResourceFile* aResFile, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray) + { + // get state screen map +#if defined(__WINS__) + TInt screenMapResource = R_AKNPRIV_HARDWARE_STATE_SCREEN_MAP_EMUL; +#else + TInt screenMapResource = R_AKNPRIV_HARDWARE_STATE_SCREEN_MAP; +#endif + + // open the resource table for the hardware state <-> screen map + TResourceReader reader; + reader.SetBuffer(aResFile->AllocReadLC(screenMapResource)); + + // Read the entires + TInt numScreenModes = aScreenInfoArray.Count(); + TInt count = reader.ReadInt16(); + aHardwareStateArray.ReserveL(count); + for (TInt ii=0; ii(reader.ReadInt16()); + CFbsBitGc::TGraphicsOrientation altRotation = static_cast(reader.ReadInt16()); + TSize altSize(height, width); + if ((rotation % CFbsBitGc::EGraphicsOrientationRotated180) == + (altRotation % CFbsBitGc::EGraphicsOrientationRotated180)) + altSize = size; + + // find a matching screen number + for (TInt jj=0; jj& aHardwareStateArray) + { + // get the state key map +#if defined(__WINS__) + TInt hwMapResource = R_AKNPRIV_HARDWARE_STATE_KEY_MAP_EMUL; +#else + TInt hwMapResource = R_AKNPRIV_HARDWARE_STATE_KEY_MAP; +#endif + + TResourceReader reader; + reader.SetBuffer(aResFile->AllocReadLC(hwMapResource)); + + TInt count = reader.ReadInt16(); + for (TInt ii=0; iiAllocReadLC(skResource)); + TAknPrivSoftkeyLocation softKeyLocation = (TAknPrivSoftkeyLocation)reader.ReadInt16(); + + CleanupStack::PopAndDestroy(); // reader's HBufC + + return softKeyLocation; + } + +TBool IsLandscape(const TSize& aSize) + { + return aSize.iWidth > aSize.iHeight; + } + +void CAknLayoutConfig::GetScreenModesFromWservL(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + TAknPrivSoftkeyLocation aLandscapeSoftkeyLocation) + { + CEikonEnv* eikonEnv = CEikonEnv::Static(); + CWsScreenDevice* dev = eikonEnv->ScreenDevice(); + + TInt numScreenModes = dev->NumScreenModes(); + aConfig.iNumScreenModes = numScreenModes; + aScreenInfoArray.ReserveL(numScreenModes); + for (TInt ii=0; iiGetScreenModeSizeAndRotation(ii, screenMode.iPixelsTwipsAndRotation); + if (IsLandscape(screenMode.iPixelsTwipsAndRotation.iPixelSize)) + { + screenMode.iSoftkeyLocation = aLandscapeSoftkeyLocation; + // side-swapping logic moved from CAknEnv::StatusPaneResIdForCurrentLayout + if (screenMode.iPixelsTwipsAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationRotated270) + { + if (aLandscapeSoftkeyLocation == EAknPrivSoftkeyLocationRight) + screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationLeft; + else if (aLandscapeSoftkeyLocation == EAknPrivSoftkeyLocationLeft) + screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationRight; + } + } + else + { + screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationBottom; + } + screenMode.iDisplayMode = dev->GetScreenModeDisplayMode(ii); + aScreenInfoArray.AppendL(screenMode); + } + } + +// +// CAknLayoutConfigWsiniParser +// +#define WSINI_PARSE_ENTRY(keyword, func) { _S(keyword), sizeof(keyword)-1, &CAknLayoutConfigWsiniParser::Call##func } +const CAknLayoutConfigWsiniParser::SParseEntry CAknLayoutConfigWsiniParser::iParseTable[] = + { + WSINI_PARSE_ENTRY("S60_HWSTATE_KEYCODE", HardwareStateKeycodeL), //S60_HWSTATE_KEYCODEn + WSINI_PARSE_ENTRY("S60_HWSTATE_SCREENMODE", HardwareStateScreenModeL), //S60_HWSTATE_SCREENMODEn + WSINI_PARSE_ENTRY("S60_HWSTATE_ALT_SCREENMODE", HardwareStateAltScreenModeL), //S60_HWSTATE_ALT_SCREENMODEn + WSINI_PARSE_ENTRY("S60_SCR_SOFTKEY_LOCATION", ScreenModeSoftkeyLocationL), //S60_SCR_SOFTKEY_LOCATIONn + WSINI_PARSE_ENTRY("S60_SCR_STYLE_NAME", ScreenModeStyleNameL), //S60_SCR_STYLE_NAMEn + }; + +void CAknLayoutConfigWsiniParser::GetConfigL(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray) + { + CAknLayoutConfigWsiniParser* self = new(ELeave) CAknLayoutConfigWsiniParser(aConfig, aScreenInfoArray, aHardwareStateArray); + CleanupStack::PushL(self); + self->GetConfigL(); + CleanupStack::PopAndDestroy(); + } + +CAknLayoutConfigWsiniParser::CAknLayoutConfigWsiniParser(SAknLayoutConfig& aConfig, + RArray& aScreenInfoArray, + RArray& aHardwareStateArray) +: iConfig(aConfig), iScreenInfoArray(aScreenInfoArray), iHardwareStateArray(aHardwareStateArray) + { + } + +CAknLayoutConfigWsiniParser::~CAknLayoutConfigWsiniParser() + { + } + +void CAknLayoutConfigWsiniParser::GetConfigL() + { + HBufC* wsini = GetWsiniLC(); + ParseWsiniL(*wsini); + CleanupStack::PopAndDestroy(wsini); + } + +void CAknLayoutConfigWsiniParser::HardwareStateKeycodeL(TPtrC& aLine) + { + //S60_HWSTATE_KEYCODEn + TInt stateNumber = ParseIntL(aLine); + TInt keyCode = ParseKeycodeL(aLine); + HardwareStateL(stateNumber).iKeyCode = keyCode; + } + +void CAknLayoutConfigWsiniParser::HardwareStateScreenModeL(TPtrC& aLine) + { + //S60_HWSTATE_SCREENMODEn + TInt stateNumber = ParseIntL(aLine); + TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers + HardwareStateL(stateNumber).iScreenMode = modeNumber; + } + +void CAknLayoutConfigWsiniParser::HardwareStateAltScreenModeL(TPtrC& aLine) + { + //S60_HWSTATE_ALT_SCREENMODEn + TInt stateNumber = ParseIntL(aLine); + TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers + HardwareStateL(stateNumber).iAltScreenMode = modeNumber; + } + +void CAknLayoutConfigWsiniParser::ScreenModeSoftkeyLocationL(TPtrC& aLine) + { + //S60_SCR_SOFTKEY_LOCATIONn + TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers + TAknPrivSoftkeyLocation location = ParseSoftkeyLocationL(aLine); + ScreenModeL(modeNumber).iSoftkeyLocation = location; + } + +void CAknLayoutConfigWsiniParser::ScreenModeStyleNameL(TPtrC& aLine) + { + //S60_SCR_STYLE_NAMEn + TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers + TInt hash = ScreenStyleHash(aLine); + ScreenModeL(modeNumber).iScreenStyleHash = hash; + } + +HBufC* CAknLayoutConfigWsiniParser::GetWsiniLC() + { + RFs& fs = CEikonEnv::Static()->FsSession(); + _LIT(KWsini, "z:\\system\\data\\wsini.ini"); + TEntry wsiniEntry; + User::LeaveIfError(fs.Entry(KWsini, wsiniEntry)); + + HBufC* wsiniText = HBufC::NewLC((wsiniEntry.iSize+1)/2); // +1 /2 to round up and convert file size to UTF-16 character size + TPtr wsiniPtr = wsiniText->Des(); + TPtr8 wsiniPtr8((TText8*)wsiniPtr.Ptr(), 0, wsiniPtr.MaxLength()*2); + + RFile wsiniFile; + User::LeaveIfError(wsiniFile.Open(fs, KWsini, EFileRead | EFileShareReadersOnly)); + CleanupClosePushL(wsiniFile); + + User::LeaveIfError(wsiniFile.Read(wsiniPtr8, wsiniEntry.iSize)); + wsiniPtr.SetLength(wsiniPtr8.Length()/2); + + CleanupStack::PopAndDestroy(&wsiniFile); + + return wsiniText; + } + +inline TBool IsDigit(TText aChar) + { + return ('0' <= aChar && aChar <= '9'); + } + +inline TBool IsKeywordChar(TText aChar) + { + return ('A' <= aChar && aChar <= 'Z') || + IsDigit(aChar) || + aChar == '_'; + } + +inline TBool IsEndOfLine(TText aChar) + { + return aChar == '\r' || aChar == '\n'; + } + +void CAknLayoutConfigWsiniParser::ParseWsiniL(const TDesC& aWsini) + { + if (!aWsini.Length()) + return; + + const TText* pChar = aWsini.Ptr(); + const TText* end = pChar + aWsini.Length(); + if (*pChar == 0xFEFF || *pChar == 0xFFFE) + pChar++; // Skip, but otherwise ignore, the UTF-16 byte ordering marker (this is how it works in wserv) + + while (pChar != end) + { + // mark start of line + const TText* kwStart = pChar; + + // find end of keyword (including digits) + while (pChar != end && IsKeywordChar(*pChar)) + ++pChar; + + // mark end of keyword (including digits) + const TText* kwEnd = pChar; + + // count back to remove digits + while (kwEnd != kwStart && IsDigit(*(kwEnd-1))) + --kwEnd; + + // find end of line + while (pChar != end && !IsEndOfLine(*pChar)) + ++pChar; + + // parse the line + ParseLineL(kwStart, kwEnd, pChar); + + // find start of next line + while (pChar != end && IsEndOfLine(*pChar)) + ++pChar; + } + } + +void CAknLayoutConfigWsiniParser::ParseLineL(const TText* aKwStart, const TText* aKwEnd, const TText* aLineEnd) + { + if (aKwEnd == aKwStart) + return; + + TPtrC kw(aKwStart, aKwEnd-aKwStart); + TPtrC rest(aKwEnd, aLineEnd-aKwEnd); + + TInt targetCount = sizeof(iParseTable)/sizeof(SParseEntry); + for (TInt ii=0; ii len && aLine.Left(len) == name) + { + lex.Assign(aLine.Mid(len)); + if (lex.Val(key, EHex) == KErrNone && trans.iRangeStart <= key && key <= trans.iRangeEnd) + { + aLine.Set(lex.Remainder()); + return trans.iBase + key - trans.iRangeStart; + } + } + } + + if (aLine.Length()) + { + // use the character + key = aLine[0]; + aLine.Set(aLine.Mid(1)); + return key; + } + + User::Leave(KErrCorrupt); + return 0; + } + +TAknPrivSoftkeyLocation CAknLayoutConfigWsiniParser::ParseSoftkeyLocationL(TPtrC& aLine) + { + TAknPrivSoftkeyLocation location = EAknPrivSoftkeyLocationBottom; + TLex lex(aLine); + lex.SkipSpace(); + TPtrC token = lex.NextToken(); + if (token == _L("right")) + location = EAknPrivSoftkeyLocationRight; + else if (token == _L("left")) + location = EAknPrivSoftkeyLocationLeft; + aLine.Set(lex.Remainder()); + return location; + } + +TInt CAknLayoutConfigWsiniParser::ScreenStyleHash(TPtrC& aLine) + { + TInt hash = 0; + TLex lex(aLine); + TPtrC name = lex.NextToken(); + const TText* pChar = name.Ptr(); + const TText* end = pChar + name.Length(); + + // calculate the hash + for (; pChar != end; ++pChar) + { + hash *= KAknLayoutScreenStyleNameHashMult; + hash += *pChar; + } + + return hash; + }