1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/ewsrv/ky_tran.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,696 @@
1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\ewsrv\ky_tran.cpp
1.18 +// The main code for setting modifiers and translating raw scanCodes into
1.19 +// keyCodes. Also traps capture-keys
1.20 +//
1.21 +//
1.22 +
1.23 +
1.24 +#include <e32svr.h>
1.25 +#include <k32keys.h>
1.26 +#include <e32keys.h>
1.27 +#include <e32uid.h>
1.28 +
1.29 +enum {EDummy,EKeyDataConv,EKeyDataFunc,EKeyDataSettings};
1.30 +
1.31 +EXPORT_C CKeyTranslator* CKeyTranslator::New()
1.32 +//
1.33 +// Return the actual key translator
1.34 +//
1.35 + {
1.36 +
1.37 + CKeyTranslatorX* pS=new CKeyTranslatorX;
1.38 + if (pS && pS->Initialise()!=KErrNone)
1.39 + {
1.40 + delete pS;
1.41 + pS=NULL;
1.42 + }
1.43 + return(pS);
1.44 + }
1.45 +
1.46 +CKeyTranslatorX::CKeyTranslatorX()
1.47 +#pragma warning (disable: 4705)
1.48 + {
1.49 +#pragma warning (default: 4705)
1.50 +
1.51 + UpdateModifiers(0);
1.52 +
1.53 + }
1.54 +
1.55 +TInt CKeyTranslatorX::Initialise()
1.56 + {
1.57 + return (ChangeKeyData(_L(""))); //Set default keydata
1.58 + }
1.59 +
1.60 +TBool CKeyTranslatorX::currentlyUpperCase(void)
1.61 +//
1.62 +// Determines whether a letter should be returned as upper case given the
1.63 +// current state of the modifiers. This is used for accented characters
1.64 +// created, for example, by entering Ctrl-1 "a". Since the keyboard may be
1.65 +// configured in different ways (e.g. shift AND capslock together may result
1.66 +// in either upper or lower case letters), a dynamic function such as this
1.67 +// is necessary
1.68 +//
1.69 + {
1.70 + TInt modifiersAffectingUpperCase=0;
1.71 +
1.72 + if (iCurModifiers&EModifierCapsLock)
1.73 + modifiersAffectingUpperCase|=EModifierCapsLock;
1.74 +
1.75 + if (iCurModifiers&EModifierShift)
1.76 + modifiersAffectingUpperCase|=EModifierShift;
1.77 +
1.78 + for (TUint i=iConvTable.FirstScanCode(); i<=iConvTable.LastScanCode(); i++)
1.79 + {
1.80 + TChar ch=iConvTable.Convert(i, modifiersAffectingUpperCase).keyCode;
1.81 + if (ch.IsUpper())
1.82 + return ETrue;
1.83 + else if (ch.IsLower())
1.84 + return EFalse;
1.85 + }
1.86 + return EFalse;
1.87 + }
1.88 +
1.89 +TUint CKeyTranslatorX::executeFunctionsAndSetState(TCharExtended aChar)
1.90 +//
1.91 +// Looks up and carries out the function required for the given
1.92 +// key-code/modifiers/state
1.93 +//
1.94 + {
1.95 + TUint keyCode=EKeyNull;
1.96 + SFunc modifierFunc=iFuncTable.GetModifierFunc(aChar, iCurModifiers);
1.97 + SFuncAndState genFuncAndNewState=iFuncTable.GetGeneralFuncAndState(aChar, iCurModifiers, iCurState,
1.98 + iCurCtrlDigits.GetRadix());
1.99 +
1.100 + SetModifierState((TEventModifier)modifierFunc.funcParam,(TModifierState)modifierFunc.func);
1.101 +
1.102 + if(!(iCurModifiers&(EModifierLeftAlt|EModifierRightAlt)))
1.103 + iCurModifiers&=~EModifierAlt;
1.104 + if(!(iCurModifiers&(EModifierLeftShift|EModifierRightShift)))
1.105 + iCurModifiers&=~EModifierShift;
1.106 + if(!(iCurModifiers&(EModifierLeftFunc|EModifierRightFunc)))
1.107 + iCurModifiers&=~EModifierFunc;
1.108 + if(!(iCurModifiers&(EModifierLeftCtrl|EModifierRightCtrl)))
1.109 + iCurModifiers&=~EModifierCtrl;
1.110 +
1.111 + switch (genFuncAndNewState.func)
1.112 + {
1.113 + case EDoNothing:
1.114 + break;
1.115 + case EPassKeyThru:
1.116 + keyCode=aChar;
1.117 + break;
1.118 + case EPassSpecialKeyThru:
1.119 + iCurCtrlDigits.Reset();
1.120 + keyCode=(currentlyUpperCase())?
1.121 + User::UpperCase(genFuncAndNewState.funcParam):
1.122 + genFuncAndNewState.funcParam;
1.123 + iCurModifiers|=(EModifierSpecial);
1.124 + break;
1.125 + case EPassCtrlDigitsThru:
1.126 + if (iCurCtrlDigits.WithinLimits())
1.127 + {
1.128 + keyCode=iCurCtrlDigits.GetDigits();
1.129 + iCurModifiers|=(EModifierSpecial);
1.130 + }
1.131 + iCurCtrlDigits.Reset();
1.132 + break;
1.133 + case EAddOnCtrlDigit:
1.134 + iCurCtrlDigits.AppendDigit(aChar, iCurModifiers);
1.135 + if (iCurCtrlDigits.Terminated(iCurModifiers) && !iCurCtrlDigits.Error() && iCurCtrlDigits.WithinLimits())
1.136 + {
1.137 + keyCode=iCurCtrlDigits.GetDigits();
1.138 + iCurModifiers|=(EModifierSpecial);
1.139 + }
1.140 + break;
1.141 + }
1.142 +
1.143 + switch (genFuncAndNewState.state)
1.144 + {
1.145 + case EStateUnchanged:
1.146 + break;
1.147 + case EStateDerivedFromDigitEntered:
1.148 + iCurState=aChar.DigitValue();
1.149 + break;
1.150 + case EStateCtrlDigits:
1.151 + if (iCurCtrlDigits.Terminated(iCurModifiers) || iCurCtrlDigits.Error())
1.152 + {
1.153 + iCurState=EStateNormal;
1.154 + iCurCtrlDigits.Reset();
1.155 + }
1.156 + else
1.157 + iCurState=iCurCtrlDigits.SetStateToCtrlDigits();
1.158 + break;
1.159 + default:
1.160 + iCurState=genFuncAndNewState.state;
1.161 + if (iCurState==EStateNormal)
1.162 + iCurCtrlDigits.Reset();
1.163 + break;
1.164 + }
1.165 + return keyCode;
1.166 + }
1.167 +
1.168 +TInt CKeyTranslatorX::GetModifierState()
1.169 +//
1.170 +// Return the current modifier state
1.171 +//
1.172 + {
1.173 +
1.174 + return(iCurModifiers);
1.175 + }
1.176 +
1.177 +void CKeyTranslatorX::UpdateModifiers(TInt aModifiers)
1.178 +//
1.179 +//
1.180 +//
1.181 + {
1.182 +
1.183 + if(aModifiers == EModifierCancelRotation || aModifiers & KRotationModifiers)
1.184 + iCurModifiers &= KPersistentModifiers; // if a Rotation modifier is being updated, only keep persistent modifiers
1.185 + else
1.186 + iCurModifiers &= KPersistentModifiers|KRotationModifiers; // if not, keep Rotation modifiers also
1.187 + iCurModifiers |= aModifiers;
1.188 + iCurState = EStateNormal;
1.189 + }
1.190 +
1.191 +
1.192 +void CKeyTranslatorX::SetModifierState(TEventModifier aModifier,TModifierState aState)
1.193 +//
1.194 +// Change a modifier state
1.195 +//
1.196 + {
1.197 +
1.198 + switch(aState)
1.199 + {
1.200 + case ETurnOffModifier:
1.201 + iCurModifiers&=~aModifier;
1.202 + break;
1.203 + case ETurnOnModifier:
1.204 + iCurModifiers|=aModifier;
1.205 + break;
1.206 + case EToggleModifier:
1.207 + iCurModifiers^=aModifier;
1.208 + }
1.209 + }
1.210 +
1.211 +TBool CKeyTranslatorX::TranslateKey(TUint aScanCode, TBool aKeyUp,
1.212 + const CCaptureKeys &aCaptureKeys, TKeyData &aKeyData)
1.213 +//
1.214 +// The function called for every keyup/keydown converting the aScanCode into a
1.215 +// keyCode, carrying out the function specified in the keyboard configuration
1.216 +// tables and setting the new state of the keyboard
1.217 +//
1.218 + {
1.219 +
1.220 +#if defined(__WINS__)
1.221 + // This code extracts the character code if there is one munged
1.222 + // with the scan code. Code which does not take advantage of this
1.223 + // new facility to pass a character code as part of aScanCode should
1.224 + // be unaffected
1.225 + //
1.226 + // extract the character code
1.227 + TUint charCode=(aScanCode&0xFFFF0000)>>16;
1.228 + // extract the scan code
1.229 + aScanCode&=0x0000FFFF;
1.230 +#endif
1.231 +
1.232 + TUint oldState=iCurState;
1.233 + TCharExtended ch;
1.234 +
1.235 + iCurModifiers&=~(EModifierPureKeycode);
1.236 +
1.237 + if(aScanCode<ESpecialKeyBase || aScanCode>=(ESpecialKeyBase+ESpecialKeyCount))
1.238 + {
1.239 + SConvKeyData convKeyData=(iCurState==EStateNormal)?
1.240 + iConvTable.Convert(aScanCode, iCurModifiers):
1.241 + iConvTable.ConvertBaseCase(aScanCode, iCurModifiers);
1.242 +
1.243 + TMaskedModifiers convModifiers;
1.244 + convModifiers.iMask=KConvTableSettableModifiers;
1.245 + convModifiers.iValue=convKeyData.modifiers;
1.246 +
1.247 + MergeModifiers(iCurModifiers,convModifiers);
1.248 + ch=convKeyData.keyCode;
1.249 + }
1.250 + else
1.251 + ch=aScanCode;
1.252 +
1.253 + if (aKeyUp)
1.254 + iCurModifiers|=(EModifierKeyUp);
1.255 + else
1.256 + iCurModifiers&=~(EModifierKeyUp);
1.257 +
1.258 + aKeyData.iKeyCode=executeFunctionsAndSetState(ch);
1.259 +
1.260 + ch=aKeyData.iKeyCode;
1.261 + // prevent modifier keys returning as keypresses
1.262 + if(ch.IsModifier())
1.263 + {
1.264 + aKeyData.iKeyCode=EKeyNull;
1.265 + iCurModifiers&=~EModifierPureKeycode;
1.266 + }
1.267 +
1.268 + TBool ret;
1.269 +
1.270 + ret=(aKeyData.iKeyCode!=EKeyNull);
1.271 +
1.272 +#if defined(__WINS__)
1.273 + // see comments in __WINS__ block above
1.274 + if (charCode)
1.275 + {
1.276 + if (!(iCurModifiers & KRotationModifiers)) // if rotation modifiers not set we trust the WINDOWS translation
1.277 + {
1.278 + aKeyData.iKeyCode=charCode;
1.279 + iCurModifiers|=EModifierAutorepeatable;
1.280 + }
1.281 + ret = ETrue;
1.282 + }
1.283 +#endif
1.284 +
1.285 + if (aKeyUp
1.286 + || (aKeyData.iKeyCode==EKeyNull)
1.287 + || (iCurState!=EStateNormal)
1.288 + || (iCurState!=oldState))
1.289 + {
1.290 + iCurModifiers&=~(EModifierAutorepeatable);
1.291 + }
1.292 +
1.293 + // convert ctrl-space to EKeyNull and clear PureKeycode modifier
1.294 + if(aKeyData.iKeyCode==EKeySpace && iCurModifiers&EModifierCtrl)
1.295 + {
1.296 + aKeyData.iKeyCode=EKeyNull;
1.297 + iCurModifiers&=~EModifierPureKeycode;
1.298 + }
1.299 +
1.300 + aKeyData.iModifiers=iCurModifiers;
1.301 +
1.302 + iCurModifiers&=(KPersistentModifiers|KRotationModifiers); // only keep persistent and rotation modifiers
1.303 +
1.304 +#if defined(__WINS__)
1.305 + if (ret)
1.306 + {
1.307 + if (charCode && (iCurModifiers & KRotationModifiers))
1.308 + {
1.309 + TKeyData keyData = aKeyData;
1.310 + keyData.iKeyCode = charCode;
1.311 + aCaptureKeys.ProcessCaptureKeys(keyData);
1.312 + // Pass the key capture data to the argument
1.313 + aKeyData.iApp = keyData.iApp;
1.314 + aKeyData.iHandle = keyData.iHandle;
1.315 + aKeyData.iIsCaptureKey = keyData.iIsCaptureKey;
1.316 + }
1.317 + else
1.318 + aCaptureKeys.ProcessCaptureKeys(aKeyData);
1.319 + }
1.320 +#else
1.321 + if (ret)
1.322 + aCaptureKeys.ProcessCaptureKeys(aKeyData);
1.323 +#endif
1.324 +
1.325 + return(ret);
1.326 + }
1.327 +//
1.328 +// A miscellaneous collection of classes used in key translation
1.329 +//
1.330 +TCharExtended &TCharExtended::operator=(TUint aChar)
1.331 + {
1.332 + SetChar(aChar);
1.333 + return *this;
1.334 + }
1.335 +//
1.336 +TBool TCharExtended::IsDigitGivenRadix(TRadix aRadix) const
1.337 +// Returns true if the character is a digit given the aRadix
1.338 + {
1.339 + switch (aRadix)
1.340 + {
1.341 + case EBinary:
1.342 + return (TBool)((TUint(*this)==(TUint)'0') || (TUint(*this)==(TUint)'1'));
1.343 + case EOctal:
1.344 + return (TBool)(IsDigit() && (TUint(*this)!=(TUint)'8') && (TUint(*this)!=(TUint)'9'));
1.345 + case EDecimal:
1.346 + return IsDigit();
1.347 + case EHex:
1.348 + return IsHexDigit();
1.349 + default:
1.350 + return EFalse;
1.351 + }
1.352 + }
1.353 +//
1.354 +TBool TCharExtended::IsModifier() const
1.355 + {
1.356 + switch ((TUint)(*this))
1.357 + {
1.358 + case EKeyLeftShift:
1.359 + case EKeyLeftFunc:
1.360 + case EKeyLeftCtrl:
1.361 + case EKeyLeftAlt:
1.362 + case EKeyRightShift:
1.363 + case EKeyRightFunc:
1.364 + case EKeyRightCtrl:
1.365 + case EKeyRightAlt:
1.366 + case EKeyCapsLock:
1.367 + case EKeyNumLock:
1.368 + case EKeyScrollLock:
1.369 + case EKeyKeyboardExtend:
1.370 + return ETrue;
1.371 + default:
1.372 + return EFalse;
1.373 + }
1.374 + }
1.375 +//
1.376 +TInt TCharExtended::DigitValue() const
1.377 +// Return the numeric value of the character if it is a digit, otherwise an errorcode
1.378 + {
1.379 + if (IsDigit())
1.380 +
1.381 + return (TInt(*this))-48;
1.382 + else if ((TInt(*this)>='A') && (TUint(*this)<='F'))
1.383 + return (TInt(*this))+10-'A';
1.384 + else if ((TInt(*this)>='a') && (TUint(*this)<='f'))
1.385 + return (TInt(*this))+10-'a';
1.386 + else
1.387 + return KErrArgument;
1.388 + }
1.389 +//
1.390 +TBool TCharExtended::MatchesPattern(const TKeyCodePattern &aKeyCodePattern, TRadix aRadix) const
1.391 +// Return true if the character matches the given pattern
1.392 + {
1.393 + switch (aKeyCodePattern.iPattern)
1.394 + {
1.395 + case EAnyKey:
1.396 + return ETrue;
1.397 + case EAnyAlphaNumeric:
1.398 + return IsAlphaDigit();
1.399 + case EAnyAlpha:
1.400 + return IsAlpha();
1.401 + case EAnyAlphaLowerCase:
1.402 + return IsLower();
1.403 + case EAnyAlphaUpperCase:
1.404 + return IsUpper();
1.405 + case EAnyDecimalDigit:
1.406 + return IsDigit();
1.407 + case EAnyDigitGivenRadix:
1.408 + return IsDigitGivenRadix(aRadix);
1.409 + case EAnyModifierKey:
1.410 + return IsModifier();
1.411 + case EMatchLeftOrRight:
1.412 + return (TBool)(TUint(*this)==aKeyCodePattern.iKeyCode || TUint(*this)==(aKeyCodePattern.iKeyCode+(TUint)1));
1.413 + case EMatchKey:
1.414 + return (TBool)(TUint(*this)==aKeyCodePattern.iKeyCode);
1.415 + case EMatchKeyCaseInsens:
1.416 + return (TBool)(User::LowerCase((TUint)*this)==User::LowerCase(aKeyCodePattern.iKeyCode));
1.417 + default:
1.418 + return EFalse;
1.419 + }
1.420 + }
1.421 +//
1.422 +typedef void (*TLibFnDataSetting)(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount,
1.423 + TInt &aMaximumCtrlDigitsMaxCount);
1.424 +
1.425 +void TCtrlDigits::Update(RLibrary aLibrary)
1.426 + {
1.427 +
1.428 + ((TLibFnDataSetting)aLibrary.Lookup(EKeyDataSettings))(iRadix,iTermination,iMaxCount,iMaximumCtrlDigitsMaxCount);
1.429 + iCount=0;
1.430 + iErrorFlag=EFalse;
1.431 + iDigits=0L;
1.432 + };
1.433 +//
1.434 +TCtrlDigits::TCtrlDigits()
1.435 + {
1.436 + };
1.437 +//
1.438 +void TCtrlDigits::Reset()
1.439 +// Reset to 0
1.440 + {
1.441 +
1.442 + iCount=0;
1.443 + iErrorFlag=EFalse;
1.444 + iDigits=0L;
1.445 + };
1.446 +//
1.447 +void TCtrlDigits::AppendDigit(TUint aKeyCode, TUint aModifiers)
1.448 +// Append the given digit to the current digits
1.449 + {
1.450 +
1.451 + TCharExtended ch=aKeyCode;
1.452 + iCount++;
1.453 + iDigits*=iRadix;
1.454 + iDigits+=ch.DigitValue();
1.455 + iErrorFlag=(TBool)(iErrorFlag
1.456 + || !ch.IsDigitGivenRadix(iRadix)
1.457 + || (iTermination==ETerminationByCtrlUp)
1.458 + && ((aModifiers&EModifierCtrl)==0));
1.459 + }
1.460 +//
1.461 +TBool TCtrlDigits::Terminated(TInt aModifiers) const
1.462 +// Return true if the digits have been terminated and are ready to return as a keyCode
1.463 + {
1.464 + return (TBool)( ((iTermination==ETerminationByCount) && (iCount>=iMaxCount))
1.465 + || ((iTermination==ETerminationByCtrlUp) && (aModifiers&EModifierCtrl)==0)
1.466 + || (iCount>=iMaximumCtrlDigitsMaxCount) );
1.467 + }
1.468 +//
1.469 +TUint TCtrlDigits::SetStateToCtrlDigits() const
1.470 +// Return either "EStateCtrlDigitsUntilCount" or "EStateCtrlDigitsUntilCtrlUp"
1.471 +// according to the current termination type
1.472 + {
1.473 + switch (iTermination)
1.474 + {
1.475 + case ETerminationByCount:
1.476 + return EStateCtrlDigitsUntilCount;
1.477 + case ETerminationByCtrlUp:
1.478 + return EStateCtrlDigitsUntilCtrlUp;
1.479 + default:
1.480 + return EStateNormal;
1.481 + }
1.482 + }
1.483 +//
1.484 +// Two classes that provide operations for accessing the keyboard configuration tables
1.485 +//
1.486 +typedef void (*TLibFnDataConv)(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode,
1.487 + SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes);
1.488 +//
1.489 +void TConvTable::Update(RLibrary aLibrary)
1.490 +#pragma warning (disable: 4705)
1.491 + {
1.492 +#pragma warning (default: 4705)
1.493 + ((TLibFnDataConv)aLibrary.Lookup(EKeyDataConv))(iConvTable,iFirstScanCode,iLastScanCode,iKeypadScanCodes,iNonAutorepKeyCodes);
1.494 + }
1.495 +//
1.496 +//
1.497 +TConvTable::TConvTable()
1.498 +#pragma warning (disable: 4705)
1.499 + {
1.500 +#pragma warning (default: 4705)
1.501 + }
1.502 +//
1.503 +TBool TConvTable::onKeypad(TUint aScanCode) const
1.504 +// Return True if the given aScanCode is on the keypad
1.505 + {
1.506 + for (TUint i=0; i<iKeypadScanCodes.numBlocks; i++)
1.507 + if ((aScanCode>=iKeypadScanCodes.pblocks[i].firstScanCode)
1.508 + && (aScanCode<=iKeypadScanCodes.pblocks[i].lastScanCode))
1.509 + {
1.510 + return ETrue;
1.511 + }
1.512 +
1.513 + return EFalse;
1.514 + }
1.515 +//
1.516 +TBool TConvTable::autorepeatable(TUint aKeyCode) const
1.517 +// Return True if the given aKeyCode is autorepeatable
1.518 + {
1.519 + for (TUint i=0; i<iNonAutorepKeyCodes.numKeyCodes; i++)
1.520 + if (aKeyCode==iNonAutorepKeyCodes.pkeyCodes[i])
1.521 + return EFalse;
1.522 +
1.523 + return ETrue;
1.524 + }
1.525 +//
1.526 +SConvKeyData TConvTable::Convert(TUint aScanCode, const TInt &aModifiers) const
1.527 +// Convert the given aScanCode and aModifiers into a keyCode and aModifiers
1.528 + {
1.529 + SConvKeyData returnVal;
1.530 + returnVal.keyCode=EKeyNull;
1.531 + returnVal.modifiers=0;
1.532 +
1.533 + for (TUint i=0; i<iConvTable.numNodes; i++)
1.534 + {
1.535 + if (MatchesMaskedValue(aModifiers,iConvTable.pnodes[i].maskedModifiers))
1.536 + {
1.537 + for (TUint j=0; j<iConvTable.pnodes[i].numSubTables; j++)
1.538 + {
1.539 + TUint offset=0;
1.540 + for (TUint k=0; k<iConvTable.pnodes[i].ppsubTables[j]->scanCodes.numBlocks; k++)
1.541 + {
1.542 + if ((aScanCode>=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode) &&
1.543 + (aScanCode<=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].lastScanCode))
1.544 + {
1.545 + returnVal.keyCode=iConvTable.pnodes[i].ppsubTables[j]->pkeyCode[offset+
1.546 + (aScanCode-iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode)];
1.547 + if (onKeypad(aScanCode))
1.548 + returnVal.modifiers|=(EModifierKeypad);
1.549 + if (autorepeatable(returnVal.keyCode))
1.550 + returnVal.modifiers|=(EModifierAutorepeatable);
1.551 +
1.552 + // check if ctrl key pressed and keycode has not been modified due to ctrl key
1.553 + if (aModifiers&EModifierCtrl && !(iConvTable.pnodes[i].maskedModifiers.iMask&EModifierCtrl))
1.554 + returnVal.modifiers|=(EModifierPureKeycode);
1.555 + return returnVal;
1.556 + }
1.557 + else
1.558 + offset+=iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].lastScanCode-
1.559 + iConvTable.pnodes[i].ppsubTables[j]->scanCodes.pblocks[k].firstScanCode+1;
1.560 + }
1.561 + }
1.562 + }
1.563 + }
1.564 + return returnVal;
1.565 + }
1.566 +//
1.567 +SConvKeyData TConvTable::ConvertBaseCase(TUint aScanCode, const TInt &aModifiers) const
1.568 +// As TConvTable::Convert above, except that all input aModifiers are ignored except for EModifierNumlock
1.569 + {
1.570 + if (aModifiers&EModifierNumLock)
1.571 + return Convert(aScanCode, EModifierNumLock);
1.572 + else
1.573 + return Convert(aScanCode, 0);
1.574 + }
1.575 +
1.576 +typedef void (*TLibFnDataFunc)(SFuncTables &aFuncTables);
1.577 +
1.578 +void TFuncTable::Update(RLibrary aLibrary)
1.579 +#pragma warning (disable: 4705)
1.580 + {
1.581 +#pragma warning (default: 4705)
1.582 + ((TLibFnDataFunc)aLibrary.Lookup(EKeyDataFunc))(iFuncTables);
1.583 + }
1.584 +//
1.585 +TFuncTable::TFuncTable()
1.586 +#pragma warning (disable: 4705)
1.587 + {
1.588 +#pragma warning (default: 4705)
1.589 + }
1.590 +//
1.591 +SFuncTableEntry TFuncTable::getDefault(const TCharExtended &aChar, const TInt &aModifiers) const
1.592 +// Get the default table entry. Should be called if passing through a normal function-table did
1.593 +// not trap these parameters.
1.594 + {
1.595 + TUint i=0;
1.596 + while(i<iFuncTables.defaultTable.numEntries)
1.597 + {
1.598 + if (aChar.MatchesPattern(iFuncTables.defaultTable.pentries[i].keyCodePattern)
1.599 + && MatchesMaskedValue(aModifiers,iFuncTables.defaultTable.pentries[i].maskedModifiers))
1.600 + {
1.601 + break;
1.602 + }
1.603 + i++;
1.604 + }
1.605 + return iFuncTables.defaultTable.pentries[i];
1.606 + }
1.607 +
1.608 +SFunc TFuncTable::GetModifierFunc(const TCharExtended &aChar, const TInt &aModifiers) const
1.609 +// Pass through the modifier table, returning the first table entry matching the given parameters.
1.610 + {
1.611 + SFuncTableEntry defaultTableEntry=getDefault(aChar, aModifiers);
1.612 + SFunc returnVal = { 0, 0, 0 };
1.613 + returnVal.func=defaultTableEntry.funcAndNewState.func;
1.614 + returnVal.funcParam=defaultTableEntry.funcAndNewState.funcParam;
1.615 +
1.616 + for (TUint i=0; i<iFuncTables.modifierTable.numEntries; i++)
1.617 + if (aChar.MatchesPattern(iFuncTables.modifierTable.pentries[i].keyCodePattern)
1.618 + && MatchesMaskedValue(aModifiers,iFuncTables.modifierTable.pentries[i].maskedModifiers))
1.619 + {
1.620 + returnVal.func=iFuncTables.modifierTable.pentries[i].funcAndNewState.func;
1.621 + returnVal.funcParam=iFuncTables.modifierTable.pentries[i].funcAndNewState.funcParam;
1.622 + return returnVal;
1.623 + }
1.624 + return returnVal;
1.625 + }
1.626 +
1.627 +SFuncAndState TFuncTable::GetGeneralFuncAndState(const TCharExtended &aChar, const TInt &aModifiers,
1.628 + TUint aCurState, TRadix aRadix) const
1.629 +// Pass through the table corresponding to the current keyboard state, returning the first
1.630 +// table entry matching the given parameters.
1.631 + {
1.632 + for (TUint i=0; i<iFuncTables.pgenFuncTables[aCurState].numEntries; i++)
1.633 + if (aChar.MatchesPattern(iFuncTables.pgenFuncTables[aCurState].pentries[i].keyCodePattern, aRadix)
1.634 + && MatchesMaskedValue(aModifiers,iFuncTables.pgenFuncTables[aCurState].pentries[i].maskedModifiers))
1.635 + {
1.636 + return iFuncTables.pgenFuncTables[aCurState].pentries[i].funcAndNewState;
1.637 + }
1.638 + return getDefault(aChar, aModifiers).funcAndNewState;
1.639 + }
1.640 +
1.641 +
1.642 +TInt CKeyTranslatorX::ChangeKeyData(const TDesC& aLibName)
1.643 +//
1.644 +// change keydata
1.645 +//
1.646 + {
1.647 +
1.648 + if(aLibName.Length()==0) // Back to default KeyData
1.649 + {
1.650 + if (!iIsdefaultKeyData)
1.651 + {
1.652 + _LIT(KEkData,"EKDATA.DLL");
1.653 + TInt r=iDefaultKeyDataLib.Load(KEkData);
1.654 + if (r!=KErrNone && r!=KErrAlreadyExists)
1.655 + return r;
1.656 + // Check for valid KeyboardData dll type
1.657 + if(iDefaultKeyDataLib.Type()[2]!=KKeyboardDataUid)
1.658 + {
1.659 + iDefaultKeyDataLib.Close();
1.660 + return(KErrCorrupt);//Only due to bad rom.
1.661 + }
1.662 + iConvTable.Update(iDefaultKeyDataLib);
1.663 + iCurCtrlDigits.Update(iDefaultKeyDataLib);
1.664 + iFuncTable.Update(iDefaultKeyDataLib);
1.665 + iIsdefaultKeyData = ETrue; // EKeyData status
1.666 + iKeyDataLib.Close(); // Close previously loaded keydata
1.667 + }
1.668 + return(KErrNone);
1.669 + }
1.670 +//
1.671 + RLibrary lib;
1.672 + TInt res=lib.Load(aLibName);
1.673 + if (res!=KErrNone && res!=KErrAlreadyExists)
1.674 + return(res);
1.675 +//
1.676 +// Check for valid KeyboardData dll type
1.677 +//
1.678 + if(lib.Type()[2]!=KKeyboardDataUid)
1.679 + {
1.680 + lib.Close();
1.681 + return(KErrArgument);
1.682 + }
1.683 +
1.684 + // Close previously loaded keydata
1.685 + if (iIsdefaultKeyData)
1.686 + {
1.687 + iIsdefaultKeyData = EFalse; // EKeyData status
1.688 + iDefaultKeyDataLib.Close();
1.689 + }
1.690 + else
1.691 + iKeyDataLib.Close();
1.692 +
1.693 + iKeyDataLib=lib;
1.694 + iConvTable.Update(lib);
1.695 + iCurCtrlDigits.Update(lib);
1.696 + iFuncTable.Update(lib);
1.697 + return(KErrNone);
1.698 + }
1.699 +