author | William Roberts <williamr@symbian.org> |
Thu, 22 Jul 2010 16:46:39 +0100 | |
branch | GCC_SURGE |
changeset 221 | 39b39e1a406e |
parent 167 | b41fc9c39ca7 |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). |
2 |
// All rights reserved. |
|
3 |
// This component and the accompanying materials are made available |
|
4 |
// under the terms of the License "Eclipse Public License v1.0" |
|
5 |
// which accompanies this distribution, and is available |
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 |
// |
|
8 |
// Initial Contributors: |
|
9 |
// Nokia Corporation - initial contribution. |
|
10 |
// |
|
11 |
// Contributors: |
|
12 |
// |
|
13 |
// Description: |
|
14 |
// e32\ewsrv\ky_tran.cpp |
|
15 |
// The main code for setting modifiers and translating raw scanCodes into |
|
16 |
// keyCodes. Also traps capture-keys |
|
17 |
// |
|
18 |
// |
|
19 |
||
20 |
||
21 |
#include <e32svr.h> |
|
22 |
#include <k32keys.h> |
|
23 |
#include <e32keys.h> |
|
24 |
#include <e32uid.h> |
|
25 |
||
26 |
enum {EDummy,EKeyDataConv,EKeyDataFunc,EKeyDataSettings}; |
|
27 |
||
28 |
EXPORT_C CKeyTranslator* CKeyTranslator::New() |
|
29 |
// |
|
30 |
// Return the actual key translator |
|
31 |
// |
|
32 |
{ |
|
33 |
||
34 |
CKeyTranslatorX* pS=new CKeyTranslatorX; |
|
35 |
if (pS && pS->Initialise()!=KErrNone) |
|
36 |
{ |
|
37 |
delete pS; |
|
38 |
pS=NULL; |
|
39 |
} |
|
40 |
return(pS); |
|
41 |
} |
|
42 |
||
43 |
CKeyTranslatorX::CKeyTranslatorX() |
|
44 |
#pragma warning (disable: 4705) |
|
45 |
{ |
|
46 |
#pragma warning (default: 4705) |
|
47 |
||
48 |
UpdateModifiers(0); |
|
49 |
||
50 |
} |
|
51 |
||
52 |
TInt CKeyTranslatorX::Initialise() |
|
53 |
{ |
|
54 |
return (ChangeKeyData(_L(""))); //Set default keydata |
|
55 |
} |
|
56 |
||
57 |
TBool CKeyTranslatorX::currentlyUpperCase(void) |
|
58 |
// |
|
59 |
// Determines whether a letter should be returned as upper case given the |
|
60 |
// current state of the modifiers. This is used for accented characters |
|
61 |
// created, for example, by entering Ctrl-1 "a". Since the keyboard may be |
|
62 |
// configured in different ways (e.g. shift AND capslock together may result |
|
63 |
// in either upper or lower case letters), a dynamic function such as this |
|
64 |
// is necessary |
|
65 |
// |
|
66 |
{ |
|
67 |
TInt modifiersAffectingUpperCase=0; |
|
68 |
||
69 |
if (iCurModifiers&EModifierCapsLock) |
|
70 |
modifiersAffectingUpperCase|=EModifierCapsLock; |
|
71 |
||
72 |
if (iCurModifiers&EModifierShift) |
|
73 |
modifiersAffectingUpperCase|=EModifierShift; |
|
74 |
||
75 |
for (TUint i=iConvTable.FirstScanCode(); i<=iConvTable.LastScanCode(); i++) |
|
76 |
{ |
|
77 |
TChar ch=iConvTable.Convert(i, modifiersAffectingUpperCase).keyCode; |
|
78 |
if (ch.IsUpper()) |
|
79 |
return ETrue; |
|
80 |
else if (ch.IsLower()) |
|
81 |
return EFalse; |
|
82 |
} |
|
83 |
return EFalse; |
|
84 |
} |
|
85 |
||
86 |
TUint CKeyTranslatorX::executeFunctionsAndSetState(TCharExtended aChar) |
|
87 |
// |
|
88 |
// Looks up and carries out the function required for the given |
|
89 |
// key-code/modifiers/state |
|
90 |
// |
|
91 |
{ |
|
92 |
TUint keyCode=EKeyNull; |
|
93 |
SFunc modifierFunc=iFuncTable.GetModifierFunc(aChar, iCurModifiers); |
|
94 |
SFuncAndState genFuncAndNewState=iFuncTable.GetGeneralFuncAndState(aChar, iCurModifiers, iCurState, |
|
95 |
iCurCtrlDigits.GetRadix()); |
|
96 |
||
97 |
SetModifierState((TEventModifier)modifierFunc.funcParam,(TModifierState)modifierFunc.func); |
|
98 |
||
99 |
if(!(iCurModifiers&(EModifierLeftAlt|EModifierRightAlt))) |
|
100 |
iCurModifiers&=~EModifierAlt; |
|
101 |
if(!(iCurModifiers&(EModifierLeftShift|EModifierRightShift))) |
|
102 |
iCurModifiers&=~EModifierShift; |
|
103 |
if(!(iCurModifiers&(EModifierLeftFunc|EModifierRightFunc))) |
|
104 |
iCurModifiers&=~EModifierFunc; |
|
105 |
if(!(iCurModifiers&(EModifierLeftCtrl|EModifierRightCtrl))) |
|
106 |
iCurModifiers&=~EModifierCtrl; |
|
107 |
||
108 |
switch (genFuncAndNewState.func) |
|
109 |
{ |
|
110 |
case EDoNothing: |
|
111 |
break; |
|
112 |
case EPassKeyThru: |
|
113 |
keyCode=aChar; |
|
114 |
break; |
|
115 |
case EPassSpecialKeyThru: |
|
116 |
iCurCtrlDigits.Reset(); |
|
117 |
keyCode=(currentlyUpperCase())? |
|
118 |
User::UpperCase(genFuncAndNewState.funcParam): |
|
119 |
genFuncAndNewState.funcParam; |
|
120 |
iCurModifiers|=(EModifierSpecial); |
|
121 |
break; |
|
122 |
case EPassCtrlDigitsThru: |
|
123 |
if (iCurCtrlDigits.WithinLimits()) |
|
124 |
{ |
|
125 |
keyCode=iCurCtrlDigits.GetDigits(); |
|
126 |
iCurModifiers|=(EModifierSpecial); |
|
127 |
} |
|
128 |
iCurCtrlDigits.Reset(); |
|
129 |
break; |
|
130 |
case EAddOnCtrlDigit: |
|
131 |
iCurCtrlDigits.AppendDigit(aChar, iCurModifiers); |
|
132 |
if (iCurCtrlDigits.Terminated(iCurModifiers) && !iCurCtrlDigits.Error() && iCurCtrlDigits.WithinLimits()) |
|
133 |
{ |
|
134 |
keyCode=iCurCtrlDigits.GetDigits(); |
|
135 |
iCurModifiers|=(EModifierSpecial); |
|
136 |
} |
|
137 |
break; |
|
138 |
} |
|
139 |
||
140 |
switch (genFuncAndNewState.state) |
|
141 |
{ |
|
142 |
case EStateUnchanged: |
|
143 |
break; |
|
144 |
case EStateDerivedFromDigitEntered: |
|
145 |
iCurState=aChar.DigitValue(); |
|
146 |
break; |
|
147 |
case EStateCtrlDigits: |
|
148 |
if (iCurCtrlDigits.Terminated(iCurModifiers) || iCurCtrlDigits.Error()) |
|
149 |
{ |
|
150 |
iCurState=EStateNormal; |
|
151 |
iCurCtrlDigits.Reset(); |
|
152 |
} |
|
153 |
else |
|
154 |
iCurState=iCurCtrlDigits.SetStateToCtrlDigits(); |
|
155 |
break; |
|
156 |
default: |
|
157 |
iCurState=genFuncAndNewState.state; |
|
158 |
if (iCurState==EStateNormal) |
|
159 |
iCurCtrlDigits.Reset(); |
|
160 |
break; |
|
161 |
} |
|
162 |
return keyCode; |
|
163 |
} |
|
164 |
||
165 |
TInt CKeyTranslatorX::GetModifierState() |
|
166 |
// |
|
167 |
// Return the current modifier state |
|
168 |
// |
|
169 |
{ |
|
170 |
||
171 |
return(iCurModifiers); |
|
172 |
} |
|
173 |
||
174 |
void CKeyTranslatorX::UpdateModifiers(TInt aModifiers) |
|
175 |
// |
|
176 |
// |
|
177 |
// |
|
178 |
{ |
|
179 |
||
180 |
if(aModifiers == EModifierCancelRotation || aModifiers & KRotationModifiers) |
|
181 |
iCurModifiers &= KPersistentModifiers; // if a Rotation modifier is being updated, only keep persistent modifiers |
|
182 |
else |
|
183 |
iCurModifiers &= KPersistentModifiers|KRotationModifiers; // if not, keep Rotation modifiers also |
|
184 |
iCurModifiers |= aModifiers; |
|
185 |
iCurState = EStateNormal; |
|
186 |
} |
|
187 |
||
188 |
||
189 |
void CKeyTranslatorX::SetModifierState(TEventModifier aModifier,TModifierState aState) |
|
190 |
// |
|
191 |
// Change a modifier state |
|
192 |
// |
|
193 |
{ |
|
194 |
||
195 |
switch(aState) |
|
196 |
{ |
|
197 |
case ETurnOffModifier: |
|
198 |
iCurModifiers&=~aModifier; |
|
199 |
break; |
|
200 |
case ETurnOnModifier: |
|
201 |
iCurModifiers|=aModifier; |
|
202 |
break; |
|
203 |
case EToggleModifier: |
|
204 |
iCurModifiers^=aModifier; |
|
205 |
} |
|
206 |
} |
|
207 |
||
208 |
TBool CKeyTranslatorX::TranslateKey(TUint aScanCode, TBool aKeyUp, |
|
209 |
const CCaptureKeys &aCaptureKeys, TKeyData &aKeyData) |
|
210 |
// |
|
211 |
// The function called for every keyup/keydown converting the aScanCode into a |
|
212 |
// keyCode, carrying out the function specified in the keyboard configuration |
|
213 |
// tables and setting the new state of the keyboard |
|
214 |
// |
|
215 |
{ |
|
216 |
||
217 |
#if defined(__WINS__) |
|
218 |
// This code extracts the character code if there is one munged |
|
219 |
// with the scan code. Code which does not take advantage of this |
|
220 |
// new facility to pass a character code as part of aScanCode should |
|
221 |
// be unaffected |
|
222 |
// |
|
223 |
// extract the character code |
|
224 |
TUint charCode=(aScanCode&0xFFFF0000)>>16; |
|
225 |
// extract the scan code |
|
226 |
aScanCode&=0x0000FFFF; |
|
227 |
#endif |
|
228 |
||
229 |
TUint oldState=iCurState; |
|
230 |
TCharExtended ch; |
|
231 |
||
232 |
iCurModifiers&=~(EModifierPureKeycode); |
|
233 |
||
234 |
if(aScanCode<ESpecialKeyBase || aScanCode>=(ESpecialKeyBase+ESpecialKeyCount)) |
|
235 |
{ |
|
236 |
SConvKeyData convKeyData=(iCurState==EStateNormal)? |
|
237 |
iConvTable.Convert(aScanCode, iCurModifiers): |
|
238 |
iConvTable.ConvertBaseCase(aScanCode, iCurModifiers); |
|
239 |
||
240 |
TMaskedModifiers convModifiers; |
|
241 |
convModifiers.iMask=KConvTableSettableModifiers; |
|
242 |
convModifiers.iValue=convKeyData.modifiers; |
|
243 |
||
244 |
MergeModifiers(iCurModifiers,convModifiers); |
|
245 |
ch=convKeyData.keyCode; |
|
246 |
} |
|
247 |
else |
|
248 |
ch=aScanCode; |
|
249 |
||
250 |
if (aKeyUp) |
|
251 |
iCurModifiers|=(EModifierKeyUp); |
|
252 |
else |
|
253 |
iCurModifiers&=~(EModifierKeyUp); |
|
254 |
||
255 |
aKeyData.iKeyCode=executeFunctionsAndSetState(ch); |
|
256 |
||
257 |
ch=aKeyData.iKeyCode; |
|
258 |
// prevent modifier keys returning as keypresses |
|
259 |
if(ch.IsModifier()) |
|
260 |
{ |
|
261 |
aKeyData.iKeyCode=EKeyNull; |
|
262 |
iCurModifiers&=~EModifierPureKeycode; |
|
263 |
} |
|
264 |
||
265 |
TBool ret; |
|
266 |
||
267 |
ret=(aKeyData.iKeyCode!=EKeyNull); |
|
268 |
||
269 |
#if defined(__WINS__) |
|
270 |
// see comments in __WINS__ block above |
|
271 |
if (charCode) |
|
272 |
{ |
|
273 |
if (!(iCurModifiers & KRotationModifiers)) // if rotation modifiers not set we trust the WINDOWS translation |
|
274 |
{ |
|
275 |
aKeyData.iKeyCode=charCode; |
|
276 |
iCurModifiers|=EModifierAutorepeatable; |
|
277 |
} |
|
278 |
ret = ETrue; |
|
279 |
} |
|
280 |
#endif |
|
281 |
||
282 |
if (aKeyUp |
|
283 |
|| (aKeyData.iKeyCode==EKeyNull) |
|
284 |
|| (iCurState!=EStateNormal) |
|
285 |
|| (iCurState!=oldState)) |
|
286 |
{ |
|
287 |
iCurModifiers&=~(EModifierAutorepeatable); |
|
288 |
} |
|
289 |
||
290 |
// convert ctrl-space to EKeyNull and clear PureKeycode modifier |
|
291 |
if(aKeyData.iKeyCode==EKeySpace && iCurModifiers&EModifierCtrl) |
|
292 |
{ |
|
293 |
aKeyData.iKeyCode=EKeyNull; |
|
294 |
iCurModifiers&=~EModifierPureKeycode; |
|
295 |
} |
|
296 |
||
297 |
aKeyData.iModifiers=iCurModifiers; |
|
298 |
||
299 |
iCurModifiers&=(KPersistentModifiers|KRotationModifiers); // only keep persistent and rotation modifiers |
|
300 |
||
301 |
#if defined(__WINS__) |
|
302 |
if (ret) |
|
303 |
{ |
|
304 |
if (charCode && (iCurModifiers & KRotationModifiers)) |
|
305 |
{ |
|
306 |
TKeyData keyData = aKeyData; |
|
307 |
keyData.iKeyCode = charCode; |
|
308 |
aCaptureKeys.ProcessCaptureKeys(keyData); |
|
309 |
// Pass the key capture data to the argument |
|
310 |
aKeyData.iApp = keyData.iApp; |
|
311 |
aKeyData.iHandle = keyData.iHandle; |
|
312 |
aKeyData.iIsCaptureKey = keyData.iIsCaptureKey; |
|
313 |
} |
|
314 |
else |
|
315 |
aCaptureKeys.ProcessCaptureKeys(aKeyData); |
|
316 |
} |
|
317 |
#else |
|
318 |
if (ret) |
|
319 |
aCaptureKeys.ProcessCaptureKeys(aKeyData); |
|
320 |
#endif |
|
321 |
||
322 |
return(ret); |
|
323 |
} |
|
324 |
// |
|
325 |
// A miscellaneous collection of classes used in key translation |
|
326 |
// |
|
327 |
TCharExtended &TCharExtended::operator=(TUint aChar) |
|
328 |
{ |
|
329 |
SetChar(aChar); |
|
330 |
return *this; |
|
331 |
} |
|
332 |
// |
|
333 |
TBool TCharExtended::IsDigitGivenRadix(TRadix aRadix) const |
|
334 |
// Returns true if the character is a digit given the aRadix |
|
335 |
{ |
|
336 |
switch (aRadix) |
|
337 |
{ |
|
338 |
case EBinary: |
|
339 |
return (TBool)((TUint(*this)==(TUint)'0') || (TUint(*this)==(TUint)'1')); |
|
340 |
case EOctal: |
|
341 |
return (TBool)(IsDigit() && (TUint(*this)!=(TUint)'8') && (TUint(*this)!=(TUint)'9')); |
|
342 |
case EDecimal: |
|
343 |
return IsDigit(); |
|
344 |
case EHex: |
|
345 |
return IsHexDigit(); |
|
346 |
default: |
|
347 |
return EFalse; |
|
348 |
} |
|
349 |
} |
|
350 |
// |
|
351 |
TBool TCharExtended::IsModifier() const |
|
352 |
{ |
|
353 |
switch ((TUint)(*this)) |
|
354 |
{ |
|
355 |
case EKeyLeftShift: |
|
356 |
case EKeyLeftFunc: |
|
357 |
case EKeyLeftCtrl: |
|
358 |
case EKeyLeftAlt: |
|
359 |
case EKeyRightShift: |
|
360 |
case EKeyRightFunc: |
|
361 |
case EKeyRightCtrl: |
|
362 |
case EKeyRightAlt: |
|
363 |
case EKeyCapsLock: |
|
364 |
case EKeyNumLock: |
|
365 |
case EKeyScrollLock: |
|
366 |
case EKeyKeyboardExtend: |
|
367 |
return ETrue; |
|
368 |
default: |
|
369 |
return EFalse; |
|
370 |
} |
|
371 |
} |
|
372 |
// |
|
373 |
TInt TCharExtended::DigitValue() const |
|
374 |
// Return the numeric value of the character if it is a digit, otherwise an errorcode |
|
375 |
{ |
|
376 |
if (IsDigit()) |
|
377 |
||
378 |
return (TInt(*this))-48; |
|
379 |
else if ((TInt(*this)>='A') && (TUint(*this)<='F')) |
|
380 |
return (TInt(*this))+10-'A'; |
|
381 |
else if ((TInt(*this)>='a') && (TUint(*this)<='f')) |
|
382 |
return (TInt(*this))+10-'a'; |
|
383 |
else |
|
384 |
return KErrArgument; |
|
385 |
} |
|
386 |
// |
|
387 |
TBool TCharExtended::MatchesPattern(const TKeyCodePattern &aKeyCodePattern, TRadix aRadix) const |
|
388 |
// Return true if the character matches the given pattern |
|
389 |
{ |
|
390 |
switch (aKeyCodePattern.iPattern) |
|
391 |
{ |
|
392 |
case EAnyKey: |
|
393 |
return ETrue; |
|
394 |
case EAnyAlphaNumeric: |
|
395 |
return IsAlphaDigit(); |
|
396 |
case EAnyAlpha: |
|
397 |
return IsAlpha(); |
|
398 |
case EAnyAlphaLowerCase: |
|
399 |
return IsLower(); |
|
400 |
case EAnyAlphaUpperCase: |
|
401 |
return IsUpper(); |
|
402 |
case EAnyDecimalDigit: |
|
403 |
return IsDigit(); |
|
404 |
case EAnyDigitGivenRadix: |
|
405 |
return IsDigitGivenRadix(aRadix); |
|
406 |
case EAnyModifierKey: |
|
407 |
return IsModifier(); |
|
408 |
case EMatchLeftOrRight: |
|
409 |
return (TBool)(TUint(*this)==aKeyCodePattern.iKeyCode || TUint(*this)==(aKeyCodePattern.iKeyCode+(TUint)1)); |
|
410 |
case EMatchKey: |
|
411 |
return (TBool)(TUint(*this)==aKeyCodePattern.iKeyCode); |
|
412 |
case EMatchKeyCaseInsens: |
|
413 |
return (TBool)(User::LowerCase((TUint)*this)==User::LowerCase(aKeyCodePattern.iKeyCode)); |
|
414 |
default: |
|
415 |
return EFalse; |
|
416 |
} |
|
417 |
} |
|
418 |
// |
|
419 |
typedef void (*TLibFnDataSetting)(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount, |
|
420 |
TInt &aMaximumCtrlDigitsMaxCount); |
|
421 |
||
422 |
void TCtrlDigits::Update(RLibrary aLibrary) |
|
423 |
{ |
|
424 |
||
425 |
((TLibFnDataSetting)aLibrary.Lookup(EKeyDataSettings))(iRadix,iTermination,iMaxCount,iMaximumCtrlDigitsMaxCount); |
|
426 |
iCount=0; |
|
427 |
iErrorFlag=EFalse; |
|
428 |
iDigits=0L; |
|
429 |
}; |
|
430 |
// |
|
431 |
TCtrlDigits::TCtrlDigits() |
|
432 |
{ |
|
433 |
}; |
|
434 |
// |
|
435 |
void TCtrlDigits::Reset() |
|
436 |
// Reset to 0 |
|
437 |
{ |
|
438 |
||
439 |
iCount=0; |
|
440 |
iErrorFlag=EFalse; |
|
441 |
iDigits=0L; |
|
442 |
}; |
|
443 |
// |
|
444 |
void TCtrlDigits::AppendDigit(TUint aKeyCode, TUint aModifiers) |
|
445 |
// Append the given digit to the current digits |
|
446 |
{ |
|
447 |
||
448 |
TCharExtended ch=aKeyCode; |
|
449 |
iCount++; |
|
450 |
iDigits*=iRadix; |
|
451 |
iDigits+=ch.DigitValue(); |
|
452 |
iErrorFlag=(TBool)(iErrorFlag |
|
453 |
|| !ch.IsDigitGivenRadix(iRadix) |
|
167
b41fc9c39ca7
1) Fix for Bug 3027 - [GCCE] Unintended operator precedence in ambiguous expressions
mikek
parents:
90
diff
changeset
|
454 |
|| ((iTermination==ETerminationByCtrlUp) |
b41fc9c39ca7
1) Fix for Bug 3027 - [GCCE] Unintended operator precedence in ambiguous expressions
mikek
parents:
90
diff
changeset
|
455 |
&& ((aModifiers&EModifierCtrl)==0))); |
0 | 456 |
} |
457 |
// |
|
458 |
TBool TCtrlDigits::Terminated(TInt aModifiers) const |
|
459 |
// Return true if the digits have been terminated and are ready to return as a keyCode |
|
460 |
{ |
|
461 |
return (TBool)( ((iTermination==ETerminationByCount) && (iCount>=iMaxCount)) |
|
462 |
|| ((iTermination==ETerminationByCtrlUp) && (aModifiers&EModifierCtrl)==0) |
|
463 |
|| (iCount>=iMaximumCtrlDigitsMaxCount) ); |
|
464 |
} |
|
465 |
// |
|
466 |
TUint TCtrlDigits::SetStateToCtrlDigits() const |
|
467 |
// Return either "EStateCtrlDigitsUntilCount" or "EStateCtrlDigitsUntilCtrlUp" |
|
468 |
// according to the current termination type |
|
469 |
{ |
|
470 |
switch (iTermination) |
|
471 |
{ |
|
472 |
case ETerminationByCount: |
|
473 |
return EStateCtrlDigitsUntilCount; |
|
474 |
case ETerminationByCtrlUp: |
|
475 |
return EStateCtrlDigitsUntilCtrlUp; |
|
476 |
default: |
|
477 |
return EStateNormal; |
|
478 |
} |
|
479 |
} |
|
480 |
// |
|
481 |
// Two classes that provide operations for accessing the keyboard configuration tables |
|
482 |
// |
|
483 |
typedef void (*TLibFnDataConv)(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode, |
|
484 |
SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes); |
|
485 |
// |
|
486 |
void TConvTable::Update(RLibrary aLibrary) |
|
487 |
#pragma warning (disable: 4705) |
|
488 |
{ |
|
489 |
#pragma warning (default: 4705) |
|
490 |
((TLibFnDataConv)aLibrary.Lookup(EKeyDataConv))(iConvTable,iFirstScanCode,iLastScanCode,iKeypadScanCodes,iNonAutorepKeyCodes); |
|
491 |
} |
|
492 |
// |
|
493 |
// |
|
494 |
TConvTable::TConvTable() |
|
495 |
#pragma warning (disable: 4705) |
|
496 |
{ |
|
497 |
#pragma warning (default: 4705) |
|
498 |
} |
|
499 |
// |
|
500 |
TBool TConvTable::onKeypad(TUint aScanCode) const |
|
501 |
// Return True if the given aScanCode is on the keypad |
|
502 |
{ |
|
503 |
for (TUint i=0; i<iKeypadScanCodes.numBlocks; i++) |
|
504 |
if ((aScanCode>=iKeypadScanCodes.pblocks[i].firstScanCode) |
|
505 |
&& (aScanCode<=iKeypadScanCodes.pblocks[i].lastScanCode)) |
|
506 |
{ |
|
507 |
return ETrue; |
|
508 |
} |
|
509 |
||
510 |
return EFalse; |
|
511 |
} |
|
512 |
// |
|
513 |
TBool TConvTable::autorepeatable(TUint aKeyCode) const |
|
514 |
// Return True if the given aKeyCode is autorepeatable |
|
515 |
{ |
|
516 |
for (TUint i=0; i<iNonAutorepKeyCodes.numKeyCodes; i++) |
|
517 |
if (aKeyCode==iNonAutorepKeyCodes.pkeyCodes[i]) |
|
518 |
return EFalse; |
|
519 |
||
520 |
return ETrue; |
|
521 |
} |
|
522 |
// |
|
523 |
SConvKeyData TConvTable::Convert(TUint aScanCode, const TInt &aModifiers) const |
|
524 |
// Convert the given aScanCode and aModifiers into a keyCode and aModifiers |
|
525 |
{ |
|
526 |
SConvKeyData returnVal; |
|
527 |
returnVal.keyCode=EKeyNull; |
|
528 |
returnVal.modifiers=0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
529 |
returnVal.filler = 0; |
0 | 530 |
|
531 |
for (TUint i=0; i<iConvTable.numNodes; i++) |
|
532 |
{ |
|
533 |
if (MatchesMaskedValue(aModifiers,iConvTable.pnodes[i].maskedModifiers)) |
|
534 |
{ |
|
535 |
for (TUint j=0; j<iConvTable.pnodes[i].numSubTables; j++) |
|
536 |
{ |
|
537 |
TUint offset=0; |
|
538 |
for (TUint k=0; k<iConvTable.pnodes[i].ppsubTables[j]->scanCodes.numBlocks; k++) |
|
539 |
{ |
|
540 |
if ((aScanCode>=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode) && |
|
541 |
(aScanCode<=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].lastScanCode)) |
|
542 |
{ |
|
543 |
returnVal.keyCode=iConvTable.pnodes[i].ppsubTables[j]->pkeyCode[offset+ |
|
544 |
(aScanCode-iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode)]; |
|
545 |
if (onKeypad(aScanCode)) |
|
546 |
returnVal.modifiers|=(EModifierKeypad); |
|
547 |
if (autorepeatable(returnVal.keyCode)) |
|
548 |
returnVal.modifiers|=(EModifierAutorepeatable); |
|
549 |
||
550 |
// check if ctrl key pressed and keycode has not been modified due to ctrl key |
|
551 |
if (aModifiers&EModifierCtrl && !(iConvTable.pnodes[i].maskedModifiers.iMask&EModifierCtrl)) |
|
552 |
returnVal.modifiers|=(EModifierPureKeycode); |
|
553 |
return returnVal; |
|
554 |
} |
|
555 |
else |
|
556 |
offset+=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].lastScanCode- |
|
557 |
iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode+1; |
|
558 |
} |
|
559 |
} |
|
560 |
} |
|
561 |
} |
|
562 |
return returnVal; |
|
563 |
} |
|
564 |
// |
|
565 |
SConvKeyData TConvTable::ConvertBaseCase(TUint aScanCode, const TInt &aModifiers) const |
|
566 |
// As TConvTable::Convert above, except that all input aModifiers are ignored except for EModifierNumlock |
|
567 |
{ |
|
568 |
if (aModifiers&EModifierNumLock) |
|
569 |
return Convert(aScanCode, EModifierNumLock); |
|
570 |
else |
|
571 |
return Convert(aScanCode, 0); |
|
572 |
} |
|
573 |
||
574 |
typedef void (*TLibFnDataFunc)(SFuncTables &aFuncTables); |
|
575 |
||
576 |
void TFuncTable::Update(RLibrary aLibrary) |
|
577 |
#pragma warning (disable: 4705) |
|
578 |
{ |
|
579 |
#pragma warning (default: 4705) |
|
580 |
((TLibFnDataFunc)aLibrary.Lookup(EKeyDataFunc))(iFuncTables); |
|
581 |
} |
|
582 |
// |
|
583 |
TFuncTable::TFuncTable() |
|
584 |
#pragma warning (disable: 4705) |
|
585 |
{ |
|
586 |
#pragma warning (default: 4705) |
|
587 |
} |
|
588 |
// |
|
589 |
SFuncTableEntry TFuncTable::getDefault(const TCharExtended &aChar, const TInt &aModifiers) const |
|
590 |
// Get the default table entry. Should be called if passing through a normal function-table did |
|
591 |
// not trap these parameters. |
|
592 |
{ |
|
593 |
TUint i=0; |
|
594 |
while(i<iFuncTables.defaultTable.numEntries) |
|
595 |
{ |
|
596 |
if (aChar.MatchesPattern(iFuncTables.defaultTable.pentries[i].keyCodePattern) |
|
597 |
&& MatchesMaskedValue(aModifiers,iFuncTables.defaultTable.pentries[i].maskedModifiers)) |
|
598 |
{ |
|
599 |
break; |
|
600 |
} |
|
601 |
i++; |
|
602 |
} |
|
603 |
return iFuncTables.defaultTable.pentries[i]; |
|
604 |
} |
|
605 |
||
606 |
SFunc TFuncTable::GetModifierFunc(const TCharExtended &aChar, const TInt &aModifiers) const |
|
607 |
// Pass through the modifier table, returning the first table entry matching the given parameters. |
|
608 |
{ |
|
609 |
SFuncTableEntry defaultTableEntry=getDefault(aChar, aModifiers); |
|
610 |
SFunc returnVal = { 0, 0, 0 }; |
|
611 |
returnVal.func=defaultTableEntry.funcAndNewState.func; |
|
612 |
returnVal.funcParam=defaultTableEntry.funcAndNewState.funcParam; |
|
613 |
||
614 |
for (TUint i=0; i<iFuncTables.modifierTable.numEntries; i++) |
|
615 |
if (aChar.MatchesPattern(iFuncTables.modifierTable.pentries[i].keyCodePattern) |
|
616 |
&& MatchesMaskedValue(aModifiers,iFuncTables.modifierTable.pentries[i].maskedModifiers)) |
|
617 |
{ |
|
618 |
returnVal.func=iFuncTables.modifierTable.pentries[i].funcAndNewState.func; |
|
619 |
returnVal.funcParam=iFuncTables.modifierTable.pentries[i].funcAndNewState.funcParam; |
|
620 |
return returnVal; |
|
621 |
} |
|
622 |
return returnVal; |
|
623 |
} |
|
624 |
||
625 |
SFuncAndState TFuncTable::GetGeneralFuncAndState(const TCharExtended &aChar, const TInt &aModifiers, |
|
626 |
TUint aCurState, TRadix aRadix) const |
|
627 |
// Pass through the table corresponding to the current keyboard state, returning the first |
|
628 |
// table entry matching the given parameters. |
|
629 |
{ |
|
630 |
for (TUint i=0; i<iFuncTables.pgenFuncTables[aCurState].numEntries; i++) |
|
631 |
if (aChar.MatchesPattern(iFuncTables.pgenFuncTables[aCurState].pentries[i].keyCodePattern, aRadix) |
|
632 |
&& MatchesMaskedValue(aModifiers,iFuncTables.pgenFuncTables[aCurState].pentries[i].maskedModifiers)) |
|
633 |
{ |
|
634 |
return iFuncTables.pgenFuncTables[aCurState].pentries[i].funcAndNewState; |
|
635 |
} |
|
636 |
return getDefault(aChar, aModifiers).funcAndNewState; |
|
637 |
} |
|
638 |
||
639 |
||
640 |
TInt CKeyTranslatorX::ChangeKeyData(const TDesC& aLibName) |
|
641 |
// |
|
642 |
// change keydata |
|
643 |
// |
|
644 |
{ |
|
645 |
||
646 |
if(aLibName.Length()==0) // Back to default KeyData |
|
647 |
{ |
|
648 |
if (!iIsdefaultKeyData) |
|
649 |
{ |
|
650 |
_LIT(KEkData,"EKDATA.DLL"); |
|
651 |
TInt r=iDefaultKeyDataLib.Load(KEkData); |
|
652 |
if (r!=KErrNone && r!=KErrAlreadyExists) |
|
653 |
return r; |
|
654 |
// Check for valid KeyboardData dll type |
|
655 |
if(iDefaultKeyDataLib.Type()[2]!=KKeyboardDataUid) |
|
656 |
{ |
|
657 |
iDefaultKeyDataLib.Close(); |
|
658 |
return(KErrCorrupt);//Only due to bad rom. |
|
659 |
} |
|
660 |
iConvTable.Update(iDefaultKeyDataLib); |
|
661 |
iCurCtrlDigits.Update(iDefaultKeyDataLib); |
|
662 |
iFuncTable.Update(iDefaultKeyDataLib); |
|
663 |
iIsdefaultKeyData = ETrue; // EKeyData status |
|
664 |
iKeyDataLib.Close(); // Close previously loaded keydata |
|
665 |
} |
|
666 |
return(KErrNone); |
|
667 |
} |
|
668 |
// |
|
669 |
RLibrary lib; |
|
670 |
TInt res=lib.Load(aLibName); |
|
671 |
if (res!=KErrNone && res!=KErrAlreadyExists) |
|
672 |
return(res); |
|
673 |
// |
|
674 |
// Check for valid KeyboardData dll type |
|
675 |
// |
|
676 |
if(lib.Type()[2]!=KKeyboardDataUid) |
|
677 |
{ |
|
678 |
lib.Close(); |
|
679 |
return(KErrArgument); |
|
680 |
} |
|
681 |
||
682 |
// Close previously loaded keydata |
|
683 |
if (iIsdefaultKeyData) |
|
684 |
{ |
|
685 |
iIsdefaultKeyData = EFalse; // EKeyData status |
|
686 |
iDefaultKeyDataLib.Close(); |
|
687 |
} |
|
688 |
else |
|
689 |
iKeyDataLib.Close(); |
|
690 |
||
691 |
iKeyDataLib=lib; |
|
692 |
iConvTable.Update(lib); |
|
693 |
iCurCtrlDigits.Update(lib); |
|
694 |
iFuncTable.Update(lib); |
|
695 |
return(KErrNone); |
|
696 |
} |
|
697 |