os/kernelhwsrv/kernel/eka/ewsrv/ky_tran.cpp
changeset 0 bde4ae8d615e
     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 +