|
1 /* |
|
2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Layout configuration data retrieval and access |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "AknLayoutConfig.h" |
|
20 #include <eikenv.h> |
|
21 #include <AknPanic.h> |
|
22 #include <aknpriv.rsg> |
|
23 #include <barsread.h> |
|
24 #include <barsc2.h> |
|
25 #include "AknLib.h" |
|
26 #include <AknLayoutConsts.h> |
|
27 #include "AknLayoutConfigInternal.h" |
|
28 #include <CdlTypes.h> |
|
29 #include <AknCapServerClient.h> |
|
30 |
|
31 NONSHARABLE_CLASS(CAknLayoutConfigWsiniParser) : public CBase |
|
32 { |
|
33 public: |
|
34 static void GetConfigL(SAknLayoutConfig& aConfig, |
|
35 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
36 RArray<SHardwareStateInfo>& aHardwareStateArray); |
|
37 |
|
38 private: |
|
39 CAknLayoutConfigWsiniParser(SAknLayoutConfig& aConfig, |
|
40 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
41 RArray<SHardwareStateInfo>& aHardwareStateArray); |
|
42 ~CAknLayoutConfigWsiniParser(); |
|
43 void GetConfigL(); |
|
44 HBufC* GetWsiniLC(); |
|
45 void ParseWsiniL(const TDesC& aWsini); |
|
46 void ParseLineL(const TText* aKwStart, const TText* aKwEnd, const TText* aLineEnd); |
|
47 |
|
48 SHardwareStateInfo& HardwareStateL(TInt aStateNumber); |
|
49 SAknScreenModeInfo& ScreenModeL(TInt aScreenMode); |
|
50 TInt ParseIntL(TPtrC& aLine); |
|
51 TInt ParseKeycodeL(TPtrC& aLine); |
|
52 TAknPrivSoftkeyLocation ParseSoftkeyLocationL(TPtrC& aLine); |
|
53 TInt ScreenStyleHash(TPtrC& aLine); |
|
54 |
|
55 private: |
|
56 #define WSINI_PARSE_FUNC(name) static void Call##name(CAknLayoutConfigWsiniParser* aSelf, TPtrC& aLine) { aSelf->name(aLine); } void name(TPtrC& aLine); |
|
57 WSINI_PARSE_FUNC(HardwareStateKeycodeL) |
|
58 WSINI_PARSE_FUNC(HardwareStateScreenModeL) |
|
59 WSINI_PARSE_FUNC(HardwareStateAltScreenModeL) |
|
60 WSINI_PARSE_FUNC(ScreenModeSoftkeyLocationL) |
|
61 WSINI_PARSE_FUNC(ScreenModeStyleNameL) |
|
62 |
|
63 private: |
|
64 struct SParseEntry |
|
65 { |
|
66 const TText16* iKeyword; |
|
67 TInt iKeywordLen; |
|
68 void (*iFunc)(CAknLayoutConfigWsiniParser* aSelf, TPtrC& aLine); |
|
69 }; |
|
70 static const SParseEntry iParseTable[]; |
|
71 |
|
72 private: |
|
73 SAknLayoutConfig& iConfig; |
|
74 RArray<SAknScreenModeInfo>& iScreenInfoArray; |
|
75 RArray<SHardwareStateInfo>& iHardwareStateArray; |
|
76 }; |
|
77 |
|
78 // |
|
79 // CAknLayoutConfig::TScreenMode |
|
80 // |
|
81 EXPORT_C const TPixelsTwipsAndRotation& CAknLayoutConfig::TScreenMode::PixelsTwipsAndRotation() const |
|
82 { |
|
83 return iInfo.iPixelsTwipsAndRotation; |
|
84 } |
|
85 |
|
86 CAknLayoutConfig::TScreenMode::TScreenMode(const SAknScreenModeInfo& aInfo) |
|
87 : TAknScreenMode(aInfo) |
|
88 { |
|
89 } |
|
90 |
|
91 EXPORT_C TAknPrivSoftkeyLocation CAknLayoutConfig::TScreenMode::SoftkeyLocation() const |
|
92 { |
|
93 return iInfo.iSoftkeyLocation; |
|
94 } |
|
95 |
|
96 EXPORT_C TInt CAknLayoutConfig::TScreenMode::ScreenStyleHash() const |
|
97 { |
|
98 return iInfo.iScreenStyleHash; |
|
99 } |
|
100 |
|
101 |
|
102 // |
|
103 // CAknLayoutConfig::TScreenModeArray |
|
104 // |
|
105 EXPORT_C CAknLayoutConfig::TScreenMode CAknLayoutConfig::TScreenModeArray::At(TInt aIndex) const |
|
106 { |
|
107 __ASSERT_ALWAYS(0 <= aIndex && aIndex < iInfo.iNumScreenModes, Panic(EAknPanicLayoutConfigBadScreenModeIndex)); |
|
108 return TScreenMode(iInfo.iScreenModes[aIndex]); |
|
109 } |
|
110 |
|
111 EXPORT_C CAknLayoutConfig::TScreenMode CAknLayoutConfig::TScreenModeArray::Find(TInt aModeNumber) const |
|
112 { |
|
113 for (TInt ii=0; ii<iInfo.iNumScreenModes; ii++) |
|
114 { |
|
115 if (iInfo.iScreenModes[ii].iModeNumber == aModeNumber) |
|
116 return TScreenMode(iInfo.iScreenModes[ii]); |
|
117 } |
|
118 return TScreenMode(iInfo.iScreenModes[0]); |
|
119 } |
|
120 |
|
121 CAknLayoutConfig::TScreenModeArray::TScreenModeArray(const SAknLayoutConfig& aInfo) |
|
122 : TAknScreenModes(aInfo) |
|
123 { |
|
124 } |
|
125 |
|
126 |
|
127 // |
|
128 // CAknLayoutConfig::THardwareState |
|
129 // |
|
130 EXPORT_C TInt CAknLayoutConfig::THardwareState::StateNumber() const |
|
131 { |
|
132 return iInfo.iStateNum; |
|
133 } |
|
134 |
|
135 EXPORT_C TInt CAknLayoutConfig::THardwareState::KeyCode() const |
|
136 { |
|
137 return iInfo.iKeyCode; |
|
138 } |
|
139 |
|
140 EXPORT_C TInt CAknLayoutConfig::THardwareState::ScreenMode() const |
|
141 { |
|
142 return iInfo.iScreenMode; |
|
143 } |
|
144 |
|
145 EXPORT_C TInt CAknLayoutConfig::THardwareState::AlternateScreenMode() const |
|
146 { |
|
147 return iInfo.iAltScreenMode; |
|
148 } |
|
149 |
|
150 CAknLayoutConfig::THardwareState::THardwareState(const SHardwareStateInfo& aInfo) |
|
151 : iInfo(aInfo) |
|
152 { |
|
153 } |
|
154 |
|
155 |
|
156 // |
|
157 // CAknLayoutConfig::THardwareStateArray |
|
158 // |
|
159 EXPORT_C TInt CAknLayoutConfig::THardwareStateArray::Count() const |
|
160 { |
|
161 return iInfo.iNumHardwareStates; |
|
162 } |
|
163 |
|
164 EXPORT_C CAknLayoutConfig::THardwareState CAknLayoutConfig::THardwareStateArray::At(TInt aIndex) const |
|
165 { |
|
166 __ASSERT_ALWAYS(0 <= aIndex && aIndex < iInfo.iNumHardwareStates, Panic(EAknPanicLayoutConfigBadHardwareStateIndex)); |
|
167 return THardwareState(iInfo.iHardwareStates[aIndex]); |
|
168 } |
|
169 |
|
170 EXPORT_C CAknLayoutConfig::THardwareState CAknLayoutConfig::THardwareStateArray::Find(TInt aStateNumber) const |
|
171 { |
|
172 for (TInt ii=0; ii<iInfo.iNumHardwareStates; ii++) |
|
173 { |
|
174 if (iInfo.iHardwareStates[ii].iStateNum == aStateNumber) |
|
175 return THardwareState(iInfo.iHardwareStates[ii]); |
|
176 } |
|
177 return THardwareState(iInfo.iHardwareStates[0]); |
|
178 } |
|
179 |
|
180 CAknLayoutConfig::THardwareStateArray::THardwareStateArray(const SAknLayoutConfig& aInfo) |
|
181 : iInfo(aInfo) |
|
182 { |
|
183 } |
|
184 |
|
185 |
|
186 // |
|
187 // CAknLayoutConfig |
|
188 // |
|
189 EXPORT_C CAknLayoutConfig::TScreenModeArray CAknLayoutConfig::ScreenModes() const |
|
190 { |
|
191 return TScreenModeArray(*iData); |
|
192 } |
|
193 |
|
194 EXPORT_C CAknLayoutConfig::THardwareStateArray CAknLayoutConfig::HardwareStates() const |
|
195 { |
|
196 return THardwareStateArray(*iData); |
|
197 } |
|
198 |
|
199 CAknLayoutConfig::CAknLayoutConfig() |
|
200 { |
|
201 } |
|
202 |
|
203 CAknLayoutConfig::~CAknLayoutConfig() |
|
204 { |
|
205 delete iBuf; |
|
206 } |
|
207 |
|
208 EXPORT_C CAknLayoutConfig* CAknLayoutConfig::NewL() |
|
209 { |
|
210 CAknLayoutConfig* self = new(ELeave) CAknLayoutConfig; |
|
211 CleanupStack::PushL(self); |
|
212 |
|
213 RAknUiServer aknUiServer; |
|
214 CleanupClosePushL(aknUiServer); |
|
215 User::LeaveIfError(aknUiServer.Connect()); |
|
216 HBufC8* configBuf = aknUiServer.GetPackedConfigL(); |
|
217 CleanupStack::PopAndDestroy(&aknUiServer); |
|
218 |
|
219 // ownership of configBuf immediately transferred to self |
|
220 self->ConstructL(configBuf); |
|
221 CleanupStack::Pop(self); |
|
222 return self; |
|
223 } |
|
224 |
|
225 #define UNPACK_CHECK(b) __ASSERT_ALWAYS(b, Panic(EAknPanicLayoutConfigUnpackFail)) |
|
226 |
|
227 void CAknLayoutConfig::ConstructL(HBufC8* aBuf) |
|
228 { |
|
229 iBuf = aBuf; |
|
230 |
|
231 // unpack & validate data |
|
232 TInt size = iBuf->Size(); |
|
233 // basic structure |
|
234 UNPACK_CHECK(size >= sizeof(SAknLayoutConfig)); |
|
235 iData = (SAknLayoutConfig*)iBuf->Ptr(); |
|
236 |
|
237 // check total size |
|
238 UNPACK_CHECK( |
|
239 size == |
|
240 ( |
|
241 sizeof(SAknLayoutConfig) + |
|
242 (iData->iNumScreenModes * sizeof(SAknScreenModeInfo)) + |
|
243 (iData->iNumHardwareStates * sizeof(SHardwareStateInfo)) |
|
244 )); |
|
245 |
|
246 // check and unpack screen modes, iScreenModes is an offset before unpacking |
|
247 UNPACK_CHECK((TUint32)iData->iScreenModes == sizeof(SAknLayoutConfig)); |
|
248 iData->iScreenModes = (SAknScreenModeInfo*)((TUint8*)iData + (TUint32)iData->iScreenModes); |
|
249 |
|
250 // check iNumScreenModes (we've already checked it fits in size) |
|
251 UNPACK_CHECK(iData->iNumScreenModes >= 0); |
|
252 |
|
253 // check and unpack hardware states, iHardwareStates is an offset before unpacking |
|
254 UNPACK_CHECK((TUint32)iData->iHardwareStates == (sizeof(SAknLayoutConfig) + sizeof(SAknScreenModeInfo)*iData->iNumScreenModes)); |
|
255 iData->iHardwareStates = (SHardwareStateInfo*)((TUint8*)iData + (TUint32)iData->iHardwareStates); |
|
256 |
|
257 // check iNumHardwareStates (we've already checked it fits in size) |
|
258 UNPACK_CHECK(iData->iNumHardwareStates >= 0); |
|
259 } |
|
260 |
|
261 HBufC8* CAknLayoutConfig::CreatePackedBufL() |
|
262 { |
|
263 // set up structures to collect the config info |
|
264 SAknLayoutConfig config = { 0, NULL, 0, NULL }; |
|
265 |
|
266 RArray<SAknScreenModeInfo> screenInfoArray; |
|
267 CleanupClosePushL(screenInfoArray); |
|
268 |
|
269 RArray<SHardwareStateInfo> hardwareStateArray; |
|
270 CleanupClosePushL(hardwareStateArray); |
|
271 |
|
272 // get the config info |
|
273 TRAP_IGNORE(GetConfigL(config, screenInfoArray, hardwareStateArray)); |
|
274 |
|
275 // calculate how much space is needed for the config info |
|
276 TInt screenModesSize = sizeof(SAknScreenModeInfo) * screenInfoArray.Count(); |
|
277 TInt hardwareStatesSize = sizeof(SHardwareStateInfo) * hardwareStateArray.Count(); |
|
278 TInt bufSize = sizeof(SAknLayoutConfig) + screenModesSize + hardwareStatesSize; |
|
279 |
|
280 // create the buffer space |
|
281 HBufC8* buf = HBufC8::NewLC(bufSize); |
|
282 TPtr8 des(buf->Des()); |
|
283 |
|
284 // pack the info for transport |
|
285 config.iScreenModes = (SAknScreenModeInfo*)sizeof(SAknLayoutConfig); |
|
286 config.iHardwareStates = (SHardwareStateInfo*)(sizeof(SAknLayoutConfig) + screenModesSize); |
|
287 |
|
288 // put the info into the buffer |
|
289 des.Append(TPckgC<SAknLayoutConfig>(config)); |
|
290 if (screenModesSize) |
|
291 des.Append(TPtrC8((TText8*)&screenInfoArray[0], screenModesSize)); |
|
292 if (hardwareStatesSize) |
|
293 des.Append(TPtrC8((TText8*)&hardwareStateArray[0], hardwareStatesSize)); |
|
294 |
|
295 // tidy up and return |
|
296 CleanupStack::Pop(buf); |
|
297 CleanupStack::PopAndDestroy(2); // hardwareStateArray and screenInfoArray |
|
298 |
|
299 return buf; |
|
300 } |
|
301 |
|
302 #ifdef _DEBUG |
|
303 void DebugLayoutConfigLeaves(TAny*) |
|
304 { |
|
305 User::Panic(_L("LayoutConfigLeave"), 0); |
|
306 } |
|
307 #endif |
|
308 |
|
309 void CAknLayoutConfig::GetConfigL(SAknLayoutConfig& aConfig, |
|
310 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
311 RArray<SHardwareStateInfo>& aHardwareStateArray) |
|
312 { |
|
313 #ifdef _DEBUG |
|
314 CleanupStack::PushL(TCleanupItem(DebugLayoutConfigLeaves, 0)); |
|
315 #endif |
|
316 |
|
317 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
318 CResourceFile* resFile = CResourceFile::NewLC(eikonEnv->FsSession(), CAknLibrary::PrivateResourceFile(), 0, 0); |
|
319 resFile->ConfirmSignatureL(); |
|
320 |
|
321 TAknPrivSoftkeyLocation landscapeSofkey = GetLandscapeSoftkeyLocationFromAknPrivL(resFile); |
|
322 GetScreenModesFromWservL(aConfig, aScreenInfoArray, landscapeSofkey); |
|
323 |
|
324 CAknLayoutConfigWsiniParser::GetConfigL(aConfig, aScreenInfoArray, aHardwareStateArray); |
|
325 if (aHardwareStateArray.Count() == 0) |
|
326 { |
|
327 // got no info from wsini, so look up AknPriv |
|
328 GetScreenMapFromAknPrivL(resFile, aScreenInfoArray, aHardwareStateArray); |
|
329 GetKeyMapFromAknPrivL(resFile, aHardwareStateArray); |
|
330 } |
|
331 aConfig.iNumHardwareStates = aHardwareStateArray.Count(); |
|
332 |
|
333 CleanupStack::PopAndDestroy(resFile); |
|
334 |
|
335 #ifdef _DEBUG |
|
336 CleanupStack::Pop(); // TCleanupItem(DebugLayoutConfigLeaves, 0) |
|
337 #endif |
|
338 } |
|
339 |
|
340 void CAknLayoutConfig::GetScreenMapFromAknPrivL(CResourceFile* aResFile, |
|
341 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
342 RArray<SHardwareStateInfo>& aHardwareStateArray) |
|
343 { |
|
344 // get state screen map |
|
345 #if defined(__WINS__) |
|
346 TInt screenMapResource = R_AKNPRIV_HARDWARE_STATE_SCREEN_MAP_EMUL; |
|
347 #else |
|
348 TInt screenMapResource = R_AKNPRIV_HARDWARE_STATE_SCREEN_MAP; |
|
349 #endif |
|
350 |
|
351 // open the resource table for the hardware state <-> screen map |
|
352 TResourceReader reader; |
|
353 reader.SetBuffer(aResFile->AllocReadLC(screenMapResource)); |
|
354 |
|
355 // Read the entires |
|
356 TInt numScreenModes = aScreenInfoArray.Count(); |
|
357 TInt count = reader.ReadInt16(); |
|
358 aHardwareStateArray.ReserveL(count); |
|
359 for (TInt ii=0; ii<count; ii++) |
|
360 { |
|
361 SHardwareStateInfo hwInfo; |
|
362 Mem::FillZ(&hwInfo, sizeof(hwInfo)); |
|
363 |
|
364 hwInfo.iStateNum = reader.ReadInt16(); |
|
365 |
|
366 TInt width = reader.ReadInt16(); |
|
367 TInt height = reader.ReadInt16(); |
|
368 TSize size(width, height); |
|
369 CFbsBitGc::TGraphicsOrientation rotation = static_cast<CFbsBitGc::TGraphicsOrientation>(reader.ReadInt16()); |
|
370 CFbsBitGc::TGraphicsOrientation altRotation = static_cast<CFbsBitGc::TGraphicsOrientation>(reader.ReadInt16()); |
|
371 TSize altSize(height, width); |
|
372 if ((rotation % CFbsBitGc::EGraphicsOrientationRotated180) == |
|
373 (altRotation % CFbsBitGc::EGraphicsOrientationRotated180)) |
|
374 altSize = size; |
|
375 |
|
376 // find a matching screen number |
|
377 for (TInt jj=0; jj<numScreenModes; jj++) |
|
378 { |
|
379 SAknScreenModeInfo& screenMode = aScreenInfoArray[jj]; |
|
380 if (screenMode.iPixelsTwipsAndRotation.iPixelSize == size && screenMode.iPixelsTwipsAndRotation.iRotation == rotation) |
|
381 hwInfo.iScreenMode = screenMode.iModeNumber; |
|
382 if (screenMode.iPixelsTwipsAndRotation.iPixelSize == altSize && screenMode.iPixelsTwipsAndRotation.iRotation == altRotation) |
|
383 hwInfo.iAltScreenMode = screenMode.iModeNumber; |
|
384 } |
|
385 |
|
386 aHardwareStateArray.AppendL(hwInfo); |
|
387 } |
|
388 |
|
389 CleanupStack::PopAndDestroy(); // reader's HBufC |
|
390 } |
|
391 |
|
392 void CAknLayoutConfig::GetKeyMapFromAknPrivL(CResourceFile* aResFile, |
|
393 RArray<SHardwareStateInfo>& aHardwareStateArray) |
|
394 { |
|
395 // get the state key map |
|
396 #if defined(__WINS__) |
|
397 TInt hwMapResource = R_AKNPRIV_HARDWARE_STATE_KEY_MAP_EMUL; |
|
398 #else |
|
399 TInt hwMapResource = R_AKNPRIV_HARDWARE_STATE_KEY_MAP; |
|
400 #endif |
|
401 |
|
402 TResourceReader reader; |
|
403 reader.SetBuffer(aResFile->AllocReadLC(hwMapResource)); |
|
404 |
|
405 TInt count = reader.ReadInt16(); |
|
406 for (TInt ii=0; ii<count; ii++) |
|
407 { |
|
408 TInt key = (TUint32)reader.ReadUint16(); |
|
409 TInt state = reader.ReadInt16(); |
|
410 for (TInt jj=0; jj<aHardwareStateArray.Count(); jj++) |
|
411 { |
|
412 SHardwareStateInfo& hwInfo = aHardwareStateArray[jj]; |
|
413 if (hwInfo.iStateNum == state) |
|
414 hwInfo.iKeyCode = key; |
|
415 } |
|
416 } |
|
417 |
|
418 CleanupStack::PopAndDestroy(); // reader's HBufC |
|
419 } |
|
420 |
|
421 TAknPrivSoftkeyLocation CAknLayoutConfig::GetLandscapeSoftkeyLocationFromAknPrivL(CResourceFile* aResFile) |
|
422 { |
|
423 #if defined(__WINS__) |
|
424 TInt skResource = R_AKNPRIV_SOFTKEY_LOCATION_LANDSCAPE_ROTATED90_EMUL; |
|
425 #else |
|
426 TInt skResource = R_AKNPRIV_SOFTKEY_LOCATION_LANDSCAPE_ROTATED90; |
|
427 #endif |
|
428 |
|
429 TResourceReader reader; |
|
430 reader.SetBuffer(aResFile->AllocReadLC(skResource)); |
|
431 TAknPrivSoftkeyLocation softKeyLocation = (TAknPrivSoftkeyLocation)reader.ReadInt16(); |
|
432 |
|
433 CleanupStack::PopAndDestroy(); // reader's HBufC |
|
434 |
|
435 return softKeyLocation; |
|
436 } |
|
437 |
|
438 TBool IsLandscape(const TSize& aSize) |
|
439 { |
|
440 return aSize.iWidth > aSize.iHeight; |
|
441 } |
|
442 |
|
443 void CAknLayoutConfig::GetScreenModesFromWservL(SAknLayoutConfig& aConfig, |
|
444 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
445 TAknPrivSoftkeyLocation aLandscapeSoftkeyLocation) |
|
446 { |
|
447 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
448 CWsScreenDevice* dev = eikonEnv->ScreenDevice(); |
|
449 |
|
450 TInt numScreenModes = dev->NumScreenModes(); |
|
451 aConfig.iNumScreenModes = numScreenModes; |
|
452 aScreenInfoArray.ReserveL(numScreenModes); |
|
453 for (TInt ii=0; ii<numScreenModes; ii++) |
|
454 { |
|
455 SAknScreenModeInfo screenMode; |
|
456 screenMode.iModeNumber = ii; |
|
457 screenMode.iScreenStyleHash = 0; |
|
458 dev->GetScreenModeSizeAndRotation(ii, screenMode.iPixelsTwipsAndRotation); |
|
459 if (IsLandscape(screenMode.iPixelsTwipsAndRotation.iPixelSize)) |
|
460 { |
|
461 screenMode.iSoftkeyLocation = aLandscapeSoftkeyLocation; |
|
462 // side-swapping logic moved from CAknEnv::StatusPaneResIdForCurrentLayout |
|
463 if (screenMode.iPixelsTwipsAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationRotated270) |
|
464 { |
|
465 if (aLandscapeSoftkeyLocation == EAknPrivSoftkeyLocationRight) |
|
466 screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationLeft; |
|
467 else if (aLandscapeSoftkeyLocation == EAknPrivSoftkeyLocationLeft) |
|
468 screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationRight; |
|
469 } |
|
470 } |
|
471 else |
|
472 { |
|
473 screenMode.iSoftkeyLocation = EAknPrivSoftkeyLocationBottom; |
|
474 } |
|
475 screenMode.iDisplayMode = dev->GetScreenModeDisplayMode(ii); |
|
476 aScreenInfoArray.AppendL(screenMode); |
|
477 } |
|
478 } |
|
479 |
|
480 // |
|
481 // CAknLayoutConfigWsiniParser |
|
482 // |
|
483 #define WSINI_PARSE_ENTRY(keyword, func) { _S(keyword), sizeof(keyword)-1, &CAknLayoutConfigWsiniParser::Call##func } |
|
484 const CAknLayoutConfigWsiniParser::SParseEntry CAknLayoutConfigWsiniParser::iParseTable[] = |
|
485 { |
|
486 WSINI_PARSE_ENTRY("S60_HWSTATE_KEYCODE", HardwareStateKeycodeL), //S60_HWSTATE_KEYCODEn <KeyCode> |
|
487 WSINI_PARSE_ENTRY("S60_HWSTATE_SCREENMODE", HardwareStateScreenModeL), //S60_HWSTATE_SCREENMODEn <ScreenModeNumber> |
|
488 WSINI_PARSE_ENTRY("S60_HWSTATE_ALT_SCREENMODE", HardwareStateAltScreenModeL), //S60_HWSTATE_ALT_SCREENMODEn <ScreenModeNumber> |
|
489 WSINI_PARSE_ENTRY("S60_SCR_SOFTKEY_LOCATION", ScreenModeSoftkeyLocationL), //S60_SCR_SOFTKEY_LOCATIONn <Location> |
|
490 WSINI_PARSE_ENTRY("S60_SCR_STYLE_NAME", ScreenModeStyleNameL), //S60_SCR_STYLE_NAMEn <ScreenStyleName> |
|
491 }; |
|
492 |
|
493 void CAknLayoutConfigWsiniParser::GetConfigL(SAknLayoutConfig& aConfig, |
|
494 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
495 RArray<SHardwareStateInfo>& aHardwareStateArray) |
|
496 { |
|
497 CAknLayoutConfigWsiniParser* self = new(ELeave) CAknLayoutConfigWsiniParser(aConfig, aScreenInfoArray, aHardwareStateArray); |
|
498 CleanupStack::PushL(self); |
|
499 self->GetConfigL(); |
|
500 CleanupStack::PopAndDestroy(); |
|
501 } |
|
502 |
|
503 CAknLayoutConfigWsiniParser::CAknLayoutConfigWsiniParser(SAknLayoutConfig& aConfig, |
|
504 RArray<SAknScreenModeInfo>& aScreenInfoArray, |
|
505 RArray<SHardwareStateInfo>& aHardwareStateArray) |
|
506 : iConfig(aConfig), iScreenInfoArray(aScreenInfoArray), iHardwareStateArray(aHardwareStateArray) |
|
507 { |
|
508 } |
|
509 |
|
510 CAknLayoutConfigWsiniParser::~CAknLayoutConfigWsiniParser() |
|
511 { |
|
512 } |
|
513 |
|
514 void CAknLayoutConfigWsiniParser::GetConfigL() |
|
515 { |
|
516 HBufC* wsini = GetWsiniLC(); |
|
517 ParseWsiniL(*wsini); |
|
518 CleanupStack::PopAndDestroy(wsini); |
|
519 } |
|
520 |
|
521 void CAknLayoutConfigWsiniParser::HardwareStateKeycodeL(TPtrC& aLine) |
|
522 { |
|
523 //S60_HWSTATE_KEYCODEn <KeyCode> |
|
524 TInt stateNumber = ParseIntL(aLine); |
|
525 TInt keyCode = ParseKeycodeL(aLine); |
|
526 HardwareStateL(stateNumber).iKeyCode = keyCode; |
|
527 } |
|
528 |
|
529 void CAknLayoutConfigWsiniParser::HardwareStateScreenModeL(TPtrC& aLine) |
|
530 { |
|
531 //S60_HWSTATE_SCREENMODEn <ScreenModeNumber> |
|
532 TInt stateNumber = ParseIntL(aLine); |
|
533 TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers |
|
534 HardwareStateL(stateNumber).iScreenMode = modeNumber; |
|
535 } |
|
536 |
|
537 void CAknLayoutConfigWsiniParser::HardwareStateAltScreenModeL(TPtrC& aLine) |
|
538 { |
|
539 //S60_HWSTATE_ALT_SCREENMODEn <ScreenModeNumber> |
|
540 TInt stateNumber = ParseIntL(aLine); |
|
541 TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers |
|
542 HardwareStateL(stateNumber).iAltScreenMode = modeNumber; |
|
543 } |
|
544 |
|
545 void CAknLayoutConfigWsiniParser::ScreenModeSoftkeyLocationL(TPtrC& aLine) |
|
546 { |
|
547 //S60_SCR_SOFTKEY_LOCATIONn <Location> |
|
548 TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers |
|
549 TAknPrivSoftkeyLocation location = ParseSoftkeyLocationL(aLine); |
|
550 ScreenModeL(modeNumber).iSoftkeyLocation = location; |
|
551 } |
|
552 |
|
553 void CAknLayoutConfigWsiniParser::ScreenModeStyleNameL(TPtrC& aLine) |
|
554 { |
|
555 //S60_SCR_STYLE_NAMEn <ScreenStyleName> |
|
556 TInt modeNumber = ParseIntL(aLine) - 1; // -1 to translate between wsini & CWsScreenDevice mode numbers |
|
557 TInt hash = ScreenStyleHash(aLine); |
|
558 ScreenModeL(modeNumber).iScreenStyleHash = hash; |
|
559 } |
|
560 |
|
561 HBufC* CAknLayoutConfigWsiniParser::GetWsiniLC() |
|
562 { |
|
563 RFs& fs = CEikonEnv::Static()->FsSession(); |
|
564 _LIT(KWsini, "z:\\system\\data\\wsini.ini"); |
|
565 TEntry wsiniEntry; |
|
566 User::LeaveIfError(fs.Entry(KWsini, wsiniEntry)); |
|
567 |
|
568 HBufC* wsiniText = HBufC::NewLC((wsiniEntry.iSize+1)/2); // +1 /2 to round up and convert file size to UTF-16 character size |
|
569 TPtr wsiniPtr = wsiniText->Des(); |
|
570 TPtr8 wsiniPtr8((TText8*)wsiniPtr.Ptr(), 0, wsiniPtr.MaxLength()*2); |
|
571 |
|
572 RFile wsiniFile; |
|
573 User::LeaveIfError(wsiniFile.Open(fs, KWsini, EFileRead | EFileShareReadersOnly)); |
|
574 CleanupClosePushL(wsiniFile); |
|
575 |
|
576 User::LeaveIfError(wsiniFile.Read(wsiniPtr8, wsiniEntry.iSize)); |
|
577 wsiniPtr.SetLength(wsiniPtr8.Length()/2); |
|
578 |
|
579 CleanupStack::PopAndDestroy(&wsiniFile); |
|
580 |
|
581 return wsiniText; |
|
582 } |
|
583 |
|
584 inline TBool IsDigit(TText aChar) |
|
585 { |
|
586 return ('0' <= aChar && aChar <= '9'); |
|
587 } |
|
588 |
|
589 inline TBool IsKeywordChar(TText aChar) |
|
590 { |
|
591 return ('A' <= aChar && aChar <= 'Z') || |
|
592 IsDigit(aChar) || |
|
593 aChar == '_'; |
|
594 } |
|
595 |
|
596 inline TBool IsEndOfLine(TText aChar) |
|
597 { |
|
598 return aChar == '\r' || aChar == '\n'; |
|
599 } |
|
600 |
|
601 void CAknLayoutConfigWsiniParser::ParseWsiniL(const TDesC& aWsini) |
|
602 { |
|
603 if (!aWsini.Length()) |
|
604 return; |
|
605 |
|
606 const TText* pChar = aWsini.Ptr(); |
|
607 const TText* end = pChar + aWsini.Length(); |
|
608 if (*pChar == 0xFEFF || *pChar == 0xFFFE) |
|
609 pChar++; // Skip, but otherwise ignore, the UTF-16 byte ordering marker (this is how it works in wserv) |
|
610 |
|
611 while (pChar != end) |
|
612 { |
|
613 // mark start of line |
|
614 const TText* kwStart = pChar; |
|
615 |
|
616 // find end of keyword (including digits) |
|
617 while (pChar != end && IsKeywordChar(*pChar)) |
|
618 ++pChar; |
|
619 |
|
620 // mark end of keyword (including digits) |
|
621 const TText* kwEnd = pChar; |
|
622 |
|
623 // count back to remove digits |
|
624 while (kwEnd != kwStart && IsDigit(*(kwEnd-1))) |
|
625 --kwEnd; |
|
626 |
|
627 // find end of line |
|
628 while (pChar != end && !IsEndOfLine(*pChar)) |
|
629 ++pChar; |
|
630 |
|
631 // parse the line |
|
632 ParseLineL(kwStart, kwEnd, pChar); |
|
633 |
|
634 // find start of next line |
|
635 while (pChar != end && IsEndOfLine(*pChar)) |
|
636 ++pChar; |
|
637 } |
|
638 } |
|
639 |
|
640 void CAknLayoutConfigWsiniParser::ParseLineL(const TText* aKwStart, const TText* aKwEnd, const TText* aLineEnd) |
|
641 { |
|
642 if (aKwEnd == aKwStart) |
|
643 return; |
|
644 |
|
645 TPtrC kw(aKwStart, aKwEnd-aKwStart); |
|
646 TPtrC rest(aKwEnd, aLineEnd-aKwEnd); |
|
647 |
|
648 TInt targetCount = sizeof(iParseTable)/sizeof(SParseEntry); |
|
649 for (TInt ii=0; ii<targetCount; ii++) |
|
650 { |
|
651 const SParseEntry& parseEntry = iParseTable[ii]; |
|
652 TPtrC header(parseEntry.iKeyword, parseEntry.iKeywordLen); |
|
653 if (kw == header) |
|
654 { |
|
655 (*parseEntry.iFunc)(this, rest); |
|
656 break; |
|
657 } |
|
658 } |
|
659 } |
|
660 |
|
661 SHardwareStateInfo& CAknLayoutConfigWsiniParser::HardwareStateL(TInt aStateNumber) |
|
662 { |
|
663 TInt count = iHardwareStateArray.Count(); |
|
664 for (TInt ii=0; ii<count; ii++) |
|
665 { |
|
666 if (iHardwareStateArray[ii].iStateNum == aStateNumber) |
|
667 return iHardwareStateArray[ii]; |
|
668 } |
|
669 |
|
670 // not found, create a new one |
|
671 SHardwareStateInfo newInfo = { aStateNumber, 0, 0, 0 }; |
|
672 iHardwareStateArray.AppendL(newInfo); |
|
673 return iHardwareStateArray[count]; |
|
674 } |
|
675 |
|
676 SAknScreenModeInfo& CAknLayoutConfigWsiniParser::ScreenModeL(TInt aModeNumber) |
|
677 { |
|
678 TInt count = iScreenInfoArray.Count(); |
|
679 for (TInt ii=0; ii<count; ii++) |
|
680 { |
|
681 if (iScreenInfoArray[ii].iModeNumber == aModeNumber) |
|
682 return iScreenInfoArray[ii]; |
|
683 } |
|
684 |
|
685 // we failed to find the screen mode. |
|
686 User::Leave(KErrNotFound); |
|
687 return iScreenInfoArray[0]; // dummy return, will never get here. |
|
688 } |
|
689 |
|
690 TInt CAknLayoutConfigWsiniParser::ParseIntL(TPtrC& aLine) |
|
691 { |
|
692 TLex lex(aLine); |
|
693 lex.SkipSpace(); |
|
694 TInt num; |
|
695 User::LeaveIfError(lex.Val(num)); |
|
696 aLine.Set(lex.Remainder()); |
|
697 return num; |
|
698 } |
|
699 |
|
700 struct SKeyTranslation |
|
701 { |
|
702 const TDesC* iName; |
|
703 TInt iBase; |
|
704 TInt iRangeStart; |
|
705 TInt iRangeEnd; |
|
706 }; |
|
707 |
|
708 _LIT(KKeyNameApp, "EKeyApplication"); |
|
709 _LIT(KKeyNameDev, "EKeyDevice"); |
|
710 |
|
711 const SKeyTranslation KKeyTranslationTable[] = |
|
712 { |
|
713 { |
|
714 LIT_AS_DESC_PTR(KKeyNameApp), |
|
715 EKeyApplication0, |
|
716 0x0, |
|
717 0xf |
|
718 }, |
|
719 { |
|
720 LIT_AS_DESC_PTR(KKeyNameDev), |
|
721 EKeyDevice0, |
|
722 0x0, |
|
723 0xf |
|
724 }, |
|
725 { |
|
726 LIT_AS_DESC_PTR(KKeyNameApp), |
|
727 EKeyApplication10, |
|
728 0x10, |
|
729 0x1f |
|
730 }, |
|
731 { |
|
732 LIT_AS_DESC_PTR(KKeyNameDev), |
|
733 EKeyDevice10, |
|
734 0x10, |
|
735 0x1f |
|
736 } |
|
737 }; |
|
738 |
|
739 TInt CAknLayoutConfigWsiniParser::ParseKeycodeL(TPtrC& aLine) |
|
740 { |
|
741 TLex lex(aLine); |
|
742 lex.SkipSpace(); |
|
743 aLine.Set(lex.Remainder()); |
|
744 |
|
745 TUint key; |
|
746 // look in the translation table for a KeyNameXX match |
|
747 TInt count = sizeof(KKeyTranslationTable)/sizeof(SKeyTranslation); |
|
748 for (TInt ii = 0; ii < count; ii++) |
|
749 { |
|
750 const SKeyTranslation& trans = KKeyTranslationTable[ii]; |
|
751 const TDesC& name = *trans.iName; |
|
752 TInt len = name.Length(); |
|
753 if (aLine.Length() > len && aLine.Left(len) == name) |
|
754 { |
|
755 lex.Assign(aLine.Mid(len)); |
|
756 if (lex.Val(key, EHex) == KErrNone && trans.iRangeStart <= key && key <= trans.iRangeEnd) |
|
757 { |
|
758 aLine.Set(lex.Remainder()); |
|
759 return trans.iBase + key - trans.iRangeStart; |
|
760 } |
|
761 } |
|
762 } |
|
763 |
|
764 if (aLine.Length()) |
|
765 { |
|
766 // use the character |
|
767 key = aLine[0]; |
|
768 aLine.Set(aLine.Mid(1)); |
|
769 return key; |
|
770 } |
|
771 |
|
772 User::Leave(KErrCorrupt); |
|
773 return 0; |
|
774 } |
|
775 |
|
776 TAknPrivSoftkeyLocation CAknLayoutConfigWsiniParser::ParseSoftkeyLocationL(TPtrC& aLine) |
|
777 { |
|
778 TAknPrivSoftkeyLocation location = EAknPrivSoftkeyLocationBottom; |
|
779 TLex lex(aLine); |
|
780 lex.SkipSpace(); |
|
781 TPtrC token = lex.NextToken(); |
|
782 if (token == _L("right")) |
|
783 location = EAknPrivSoftkeyLocationRight; |
|
784 else if (token == _L("left")) |
|
785 location = EAknPrivSoftkeyLocationLeft; |
|
786 aLine.Set(lex.Remainder()); |
|
787 return location; |
|
788 } |
|
789 |
|
790 TInt CAknLayoutConfigWsiniParser::ScreenStyleHash(TPtrC& aLine) |
|
791 { |
|
792 TInt hash = 0; |
|
793 TLex lex(aLine); |
|
794 TPtrC name = lex.NextToken(); |
|
795 const TText* pChar = name.Ptr(); |
|
796 const TText* end = pChar + name.Length(); |
|
797 |
|
798 // calculate the hash |
|
799 for (; pChar != end; ++pChar) |
|
800 { |
|
801 hash *= KAknLayoutScreenStyleNameHashMult; |
|
802 hash += *pChar; |
|
803 } |
|
804 |
|
805 return hash; |
|
806 } |